web-dev-qa-db-ja.com

FactoryGirl:attributes_forは私に関連する属性を与えません

私はこのようなコードモデルファクトリを持っています:

Factory.define :code do |f|
    f.value "code"
    f.association :code_type
    f.association(:codeable, :factory => :portfolio)
end

しかし、次のような単純なtest_should_create_codeを使用してコントローラーをテストすると、次のようになります。

  test "should create code" do
    assert_difference('Code.count') do
      post :create, :code => Factory.attributes_for(:code)
    end
    assert_redirected_to code_path(assigns(:code))
  end

...テストは失敗します。新しいレコードは作成されません。

コンソールでは、attributes_forは、createのように必要なすべての属性を返すわけではありません。

rob@compy:~/dev/my_Rails_app$ Rails console test
Loading test environment (Rails 3.0.3)
irb(main):001:0> Factory.create(:code)
=> #<Code id: 1, code_type_id: 1, value: "code", codeable_id: 1, codeable_type: "Portfolio", created_at: "2011-02-24 10:42:20", updated_at: "2011-02-24 10:42:20">
irb(main):002:0> Factory.attributes_for(:code)
=> {:value=>"code"}

何か案は?

ありがとう、

31
Robert Brown

あなたはこのようなことを試すことができます:

(Factory.build :code).attributes.symbolize_keys 

これを確認してください: http://groups.google.com/group/factory_girl/browse_thread/thread/a95071d66d97987e

23

これはタイムスタンプなどを返しません。一括割り当てでアクセスできる属性のみを返します。

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

それでも、それはかなり醜いです。 FactoryGirlは、このようなものをすぐに提供する必要があると思います。

私はこれのリクエストを開きました ここ

10
Joshua Muheim

私はさらに別のアプローチを提案したいと思いますが、それはより明確だと思います。

attr = attributes_for(:code).merge(code_type: create(:code_type))
9
harm

これが私がやることになることです...

conf = FactoryGirl.build(:conference)
post :create, {:conference => conf.attributes.slice(*conf.class.accessible_attributes) }
2
user308096

他の人の助けになる場合に備えて、他の人が言ったことをまとめました。問題のFactoryGirlのバージョンと一貫性を保つために、FactoryGirl.build()の代わりにFactory.build()を使用しました。必要に応じて更新してください。

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

Factory.attributes_forの代わりにこのメソッドを呼び出すだけです。

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

完全な要点(ヘルパーモジュール内)はここにあります: https://Gist.github.com/jlberglund/5207078

2
Jonathan

別の方法があります。おそらく、id、_created_at_、および_updated_at_属性を省略したいと思うでしょう。

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

制限:

  • HMTおよびHABTMアソシエーションの属性は生成されません(これらのアソシエーションは実際の属性ではなく結合テーブルに格納されるため)。
  • 工場での関連付け戦略は、_association :user, strategy: :create_のように、createである必要があります。この戦略は、賢明に使用しないと、工場を非常に遅くする可能性があります。
0
BrunoFacca

私のAPP/spec/controllers/pages_controllers_spec.rbで、次のように設定しました。

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

2つのモデルが関連付けられているためです。これも機能します:

 FactoryGirl.define do 
 factory:page do 
 title {Faker :: Lorem.characters 12} 
 body {Faker :: Lorem.characters 38} 
 discustion false 
 published true 
タグ「linux、education、elearning」
セクション{FactoryGirl.create(:section)} 
ユーザー{FactoryGirl.create (:user)} 
 end 
 end 
0
aarkerio