FactoryGirl использует: parent => Ассоциации не удается - PullRequest
1 голос
/ 27 января 2012

У меня есть следующие таблицы:

  create_table "acs_objects", :force => true do |t|
     #various attributes....
  end


create_table "content_items", :force => true do |t|
    t.integer  "parent_id"
    t.string   "name"                     :limit => 400
end

В AR это соотношение имеет место: class ContentItem

Мой тест Rspec:

require 'spec_helper'

describe ContentItem do

  subject {Factory(:content_item)}
  it {should be_valid}

end

Если я определю фабрику следующим образом:

Factory.define :content_item do |ci|
  ci.sequence(:name) {|n| "Music#{n}"}
end

Я получаю сообщение об ошибке: нулевое значение в столбце «parent_id» нарушает ненулевое ограничение

Если я поменяю фабрику таким образом:

Factory.define :content_item, :parent => :acs_object do |ci|
  ci.sequence(:name) {|n| "Music#{n}"}
end

тогда я получаю эту ошибку:

NoMethodError в 'ContentItem' неопределенный метод `name = 'для AcsObject: 0xb3ee51e8

Я использовал: родительский раньше и никогда не было этой проблемы. «имя» явно принадлежит ContentItem - почему я получаю эту ошибку?

Я почти уверен, что проблема связана с тем фактом, что таблица content_items определяется как представление и сочетание родительских и дочерних атрибутов:

View definition:
 SELECT parent.id, parent.object_type, parent.context_id, parent.security_inherit_p, parent.created_by, parent.created_at, parent.created_ip, parent.updated_at, parent.updated_by, parent.updated_ip, parent.context_tree_sortkey, parent.context_max_tree_sortkey, child.parent_id, child.name, child.locale, child.live_revision AS live_revision_id, child.latest_revision AS latest_revision_id, child.publish_status, child.content_type, child.storage_type, child.storage_area_key, child.tree_sortkey, child.max_child_sortkey
   FROM acs_objects parent
   JOIN cr_items child ON parent.id = child.item_id;

Если это действительно причина, есть ли способ использовать FactoryGirl и заставить его работать как положено?

Обновление: фабрика ContentItem теперь работает. Вот изменение, которое я сделал:

Factory.define :content_item do |ci|
  ci.sequence(:name) {|n| "Music#{n}"}
  ci.parent_id      Factory(:acs_object).id
end

Есть ли лучший способ сделать это?

1 Ответ

0 голосов
/ 03 мая 2012

factory_girl предполагает, что вы хотите использовать тот же класс сборки, что и родительский, при определении дочерней фабрики.Если вы не хотите этого делать, вы можете переопределить класс в дочернем определении:

Factory.define :content_item, :parent => :acs_object, :class => "ContentItem" do |ci|
  ci.sequence(:name) {|n| "Music#{n}"}
end
...