FactoryGirl: attributes_for not giving me associated attributes

前端 未结 7 625
再見小時候
再見小時候 2020-12-08 14:08

I have a Code model factory like this:

Factory.define :code do |f|
    f.value \"code\"
    f.association :code_type
    f.association(:codeable, :factory =&         


        
相关标签:
7条回答
  • 2020-12-08 14:29

    I'd suggest yet an other approach, which I think is clearer:

    attr = attributes_for(:code).merge(code_type: create(:code_type))
    
    0 讨论(0)
  • 2020-12-08 14:38

    Here's another way. You probably want to omit the id, created_at and updated_at attributes.

    FactoryGirl.build(:car).attributes.except('id', 'created_at', 'updated_at').symbolize_keys

    Limitations:

    • It does not generate attributes for HMT and HABTM associations (as these associations are stored in a join table, not an actual attribute).
    • Association strategy in the factory must be create, as in association :user, strategy: :create. This strategy can make your factory very slow if you don't use it wisely.
    0 讨论(0)
  • 2020-12-08 14:42

    I've synthesized what others have said, in case it helps anyone else. To be consistent with the version of FactoryGirl in question, I've used Factory.build() instead of FactoryGirl.build(). Update as necessary.

    def build_attributes_for(*args)
      build_object = Factory.build(*args)
      build_object.attributes.slice(*build_object.class.accessible_attributes).symbolize_keys
    end
    

    Simply call this method in place of Factory.attributes_for:

    post :create, :code => build_attributes_for(:code)
    

    The full gist (within a helper module) is here: https://gist.github.com/jlberglund/5207078

    0 讨论(0)
  • 2020-12-08 14:45

    This one doesn't return timestamps etc., only attributes that are accessible for mass assignment:

    (FactoryGirl.build :position).attributes.symbolize_keys.reject { |key, value| !Position.attr_accessible[:default].collect { |attribute| attribute.to_sym }.include?(key) }
    

    Still, it's quite ugly. I think FactoryGirl should provide something like this out of the box.

    I opened a request for this here.

    0 讨论(0)
  • 2020-12-08 14:46

    heres what I end up doing...

    conf = FactoryGirl.build(:conference)
    post :create, {:conference => conf.attributes.slice(*conf.class.accessible_attributes) }
    
    0 讨论(0)
  • 2020-12-08 14:50

    In my APP/spec/controllers/pages_controllers_spec.rb I set:

    let(:valid_attributes) { FactoryGirl.attributes_for(:page).merge(subject: FactoryGirl.create(:theme), user: FactoryGirl.create(:user)) } 
    

    Because I have two models associated. This works too:

     FactoryGirl.define do
        factory :page do
           title      { Faker::Lorem.characters 12 }
           body       { Faker::Lorem.characters 38 }
           discution  false
           published  true
           tags       "linux, education, elearning"
           section   { FactoryGirl.create(:section) }
           user      { FactoryGirl.create(:user)    }                                                                                                                            
         end
      end
    
    0 讨论(0)
提交回复
热议问题