问题
Assume that I have a city model where:
class city
field :full_name, type: String # San Francisco, CA, United States
field :_id, type: String, overwrite: true, default: ->{ full_name }
end
Assume that I have a factory defined in /spec/factories/cities.rb:
FactoryGirl.define do
factory :city do
full_name 'San Francisco, CA, United States'
end
end
Running the following code in one of the specs:
city_attrs = { full_name: 'San Francisco, CA, United States' }
City.create! city_attrs
=> #<City _id: San Francisco, CA, United States, full_name: "San Francisco, CA, United States">
FactoryGirl.create(:city)
=> #<City _id: , full_name: "San Francisco, CA, United States">
How do I fix this without adding the following code to the /spec/factories/cities.rb?
before(:create) do |city, evaluator|
city.id = city.full_name
end
EDIT
the solution is to stop using FactoryGirl
and use Fabrication instead as recommended in this answer
回答1:
You need to override the initialization of the model used by FactoryGirl:
FactoryGirl.define do
trait :explicit_initialize do
initialize_with { new(attributes) }
end
factory :city, traits: [:explicit_initialize] do
full_name 'San Francisco, CA, United States'
end
end
回答2:
Like explain on documentation, all default define in lambda are lazy. So you need pre_process it :
When defining a default value as a proc, Mongoid will apply the default after all other attributes are set. If you want this to happen before the other attributes, set pre_processed: true.
class city
field :full_name, type: String # San Francisco, CA, United States
field :_id, type: String, overwrite: true, pre_processed: true, default: ->{ full_name }
end
来源:https://stackoverflow.com/questions/19493502/factorygirl-creates-incomplete-model