Factory_girl имеет_одно отношение с validates_presence_of

У меня есть 2 модели:

# user.rb
class User < ActiveRecord::Base
  has_one :profile, :dependent => :destroy
end

# profile.rb
class Profile < ActiveRecord::Base
  belongs_to :user
  validates_presence_of :user
end

# user_factory.rb
Factory.define :user do |u|
  u.login "test"
  u.association :profile
end

Я хочу сделать это:

@user = Factory(:user)
=> #<User id: 88,....>
@user.profile
=> #<Profile id:123, user_id:88, ......>

@user = Factory.build(:user)
=> #<User id: nil,....>
@user.profile
=> #<Profile id:nil, user_id:nil, ......>

Но это не работает! Он говорит мне, что моя модель профиля неверна, потому что нет пользователя! (он сохраняет профиль перед пользователем, поэтому нет user_id...)

Как я могу это исправить? Все перепробовал.. :( И мне нужно вызвать Factory.create(:user)...

ОБНОВЛЕНИЕ

Исправлена ​​эта проблема - теперь работает с:

# user_factory.rb
Factory.define :user do |u|
  u.profile { Factory.build(:profile)}
end

# user.rb
class User < ActiveRecord::Base
  has_one :profile, :dependent => :destroy, :inverse_of => :user
end

# profile.rb
class Profile < ActiveRecord::Base
  belongs_to :user
  validates_presence_of :user
end

person BvuRVKyUVlViVIc7    schedule 06.09.2010    source источник
comment
Я думаю, когда вы «создаете» профиль, он сохраняет его и пользователя. Вы пытались «создать» профиль с помощью Factory.build(:profile, :user =›a) на вашем factory?   -  person mb14    schedule 06.09.2010
comment
Да, пробовал, но не сработало... Мое уродливое решение выше теперь работает... Спасибо за помощь!   -  person BvuRVKyUVlViVIc7    schedule 06.09.2010


Ответы (1)


Исправьте это таким образом (, как описано в этот пост)

Factory.define :user do |u|
  u.login "test"
  u.profile { |p| p.association(:profile) }
end

Что вы также можете сделать (поскольку пользователю не нужен профиль для существования (на нем нет проверки), так это выполнить двухэтапную конструкцию

Factory.define :user do |u|
  u.login "test"
end

а потом

profile = Factory :profile
user = Factory :user, :profile => profile

Я думаю, в этом случае вам даже нужен один шаг, создайте пользователя в фабрике профилей и сделайте

profile = Factory :profile
@user = profile.user

Это кажется правильным способом сделать это, не так ли?

Обновлять

(согласно вашему комментарию) Чтобы избежать сохранения профиля, используйте Factory.build только для его сборки.

Factory.define :user do |u|
  u.login "test"
  u.after_build { |a| Factory(:profile, :user => a)}    
end
person mb14    schedule 06.09.2010
comment
Я пробовал это раньше, и это не сработало, потому что профиль сохраняется до пользователя... И поэтому validates_presence_of: user-validation не принимает сохранение... Исправлено с помощью моего решения выше! - person BvuRVKyUVlViVIc7; 06.09.2010
comment
Хорошо, не видел, чтобы ты ответил на свой же пост. Все равно это странно. Мы часто используем фабричную девушку (там, где я работаю), и я никогда не видел этой проблемы. - person mb14; 06.09.2010
comment
Хорошо... Но мое решение в конце концов не сработало. Пользователь сохраняется, даже если я вызываю Factoy.build(:user)... Не знаю почему... - person BvuRVKyUVlViVIc7; 06.09.2010
comment
Я запутался... все работает с u.profile { Factory.build(:profile)} , но не с вашим предложением u.profile { |p| p.association(:profile) }... Сумасшедший ^^ - person BvuRVKyUVlViVIc7; 06.09.2010
comment
Когда вы измените свой ответ на мое исправление выше, я отмечу ваш ответ как принятый... Спасибо! - person BvuRVKyUVlViVIc7; 07.09.2010