2012-03-12 10 views
2
factory :foo do 
    bar # want this to use foo's id in calculating bar's value 

    # current solution 
    # ugly because it requires an extra save 
    after_create { |foo| foo.bar = foo.id; foo.save! } 

    # tried this too but foo.id is still nil at this point 
    # after_build { |foo| foo.bar = foo.id } 
end 

オブジェクトの作成時にオブジェクトのIDを処理する方が良いでしょうか?上記のシナリオでこれが発生しました。別のフィールドでFactoryGirlオブジェクトIDを使用していますか?

また、fooがfoo.idを使用するActiveRecord before_create_callbackを持つ別のシナリオもあります。 ARを使用すると、オブジェクトはコールバックが呼び出され、メソッドが期待どおりに動作するときにidを持ちます。 FGでは、コールバックが呼び出されたときにオブジェクトにidがないため、メソッドが期待どおりに動作しません。ここでも、私は余分な明示的な保存でafter_createに頼っています。

FactoryGirlオブジェクトの作成中にオブジェクトIDを処理するための提案やヒントは非常に高く評価されます。

答えて

1

ここでは、irbでレールの外で動作する完全な例を示します。あなたはしかし、適切な宝石をインストールする必要があります。

のsqliteのテーブルを作成します。

sqlite3 /tmp/development.db 
> create table foos (id int, name varchar(50), primary key(id)); 
> create table bars (id int, name varchar(50), foo_id int, primary key(id)); 

注意これはfactory_girl 3.xの構文であること。

require 'factory_girl' 
require 'active_record' 
require 'active_support' 

ActiveRecord::Base.establish_connection(
    :adapter => 'sqlite3', :database => '/tmp/development.db' 
) 

class Foo < ActiveRecord::Base 
    attr_accessible :id, :name 
    has_one :bar 
end 

class Bar < ActiveRecord::Base 
    attr_accessible :id, :name 
    belongs_to :foo 
end 

FactoryGirl.define do 
    factory :foo do 
    sequence :id do |n| 
     n 
    end 
    name "Foo Name" # use Faker 
    end 
end 

FactoryGirl.define do 
    factory :bar do 
    sequence(:id) {|n| n } 
    association :foo, :factory => :foo 
    name "Bar Name" # use Faker 
    end 
end 

bar = FactoryGirl.build(:bar) 
puts bar.inspect 
# => #<Bar id: 1, name: "Bar Name", foo_id: 1> 

この実行後にテーブルをロールバックしないため、この操作は1回だけ実行できます。これはfactory_girlがアソシエーションを必要とし、すべてのレコードがbuildコールであっても、DBにレコードを書き込むためです。通常buildはDBに書き込みません。非常に非railsy例えば

> delete from foos; 
> delete from bars; 

申し訳ありませんが、少なくとも、あなたのプロジェクトいじりせずに側にこれで遊ぶことができます:あなたは、手動でロールバックすることができます。

関連する問題