对于每个User
工厂,我需要创建一个从磁盘加载图像的嵌套Photo
。我想知道如何通过简单地将文件名声明为用户工厂的属性来简化此代码。
此代码也有问题,正在保存:女性工厂文件名为avatar1.jpg
而不是avatar2.jpg
,可能是因为第一个用户之后。
FactoryGirl.define do
factory :user do
email 'john@site.com'
country 'US'
after(:create) do |user, evaluator|
photo_file = 'avatar1.jpg'
photo_object = File.new(File.join(::Rails.root.to_s, "/factories/images", photo_file), 'rb')
user.photos << FactoryGirl.build(:photo, photo: photo_object, user: user)
user.avatar_id = user.photos.first.id
user.save
end
factory :woman do
email 'annie@site'
after(:create) do |user, evaluator|
photo_file = 'avatar2.jpg'
photo_object = File.new(File.join(::Rails.root.to_s, "/factories/images", photo_file), 'rb')
user.photos << FactoryGirl.build(:photo, photo: photo_object, user: user)
user.avatar_id = user.photos.first.id
user.save
end
end
end
end
这是模型关系
# user.rb
has_many :photos, dependent: :destroy
# photo.rb
belongs_to :user
任何帮助?
答案 0 :(得分:1)
作为如何更好地组织代码的建议,您应该将文件读取逻辑移动到Photo
模型本身。例如:
class Photo < ActiveRecord::Base
attr_accessor :filename
after_initialize do |p|
if filename
p.photo = File.new(File.join(::Rails.root.to_s, filename), 'rb')
end
end
end
然后,您可以使用traits创建男性和女性用户,使用create(:user, :male)
和create(:user, :female)
,如下所示:
FactoryGirl.define do
factory :user do
country 'US'
ignore { photo_count 1 } # ignored attribute - number of photos to build per user
trait :male do
email 'john@site.com'
after(:create) do |user, evaluator|
create_list(:photo, evaluator.photo_count, :male, user: user)
end
end
trait :female do
email 'annie@site.com'
after(:create) do |user, evaluator|
create_list(:photo, evaluator.photo_count, :female, user: user)
end
end
end
factory :photo do
trait :male do
filename '/factories/images/avatar1.jpg'
end
trait :female do
filename '/factories/images/avatar2.jpg'
end
user # the user to be associated with the photo
end
end
答案 1 :(得分:0)
不完全是一个优雅的解决方案,但快速修复将是
user.avatar_id = user.photos.last.id