Rspec 如何在工厂里建厂女孩与许多人有联系

Rspec 如何在工厂里建厂女孩与许多人有联系,rspec,ruby-on-rails-3.1,has-many-through,factory-bot,Rspec,Ruby On Rails 3.1,Has Many Through,Factory Bot,有没有人能告诉我,我是不是在错误地进行设置 我有以下模型,这些模型有很多联系: class Listing < ActiveRecord::Base attr_accessible ... has_many :listing_features has_many :features, :through => :listing_features validates_presence_of ... ... end class Feature < Ac

有没有人能告诉我,我是不是在错误地进行设置

我有以下模型,这些模型有很多联系:

class Listing < ActiveRecord::Base
  attr_accessible ... 

  has_many :listing_features
  has_many :features, :through => :listing_features

  validates_presence_of ...
  ...  
end


class Feature < ActiveRecord::Base
  attr_accessible ...

  validates_presence_of ...
  validates_uniqueness_of ...

  has_many :listing_features
  has_many :listings, :through => :listing_features
end


class ListingFeature < ActiveRecord::Base
  attr_accessible :feature_id, :listing_id

  belongs_to :feature  
  belongs_to :listing
end
这里是工厂(:列表)

:listing_功能
:功能
工厂的设置类似。
如果
association:features
行被注释掉,则我的所有测试都通过。
当它是

association :features, :factory => :feature
错误消息是
未定义#
的方法“each”,我认为这对我来说是有意义的,因为
listing.features
返回一个数组。所以我把它改成了

association :features, [:factory => :feature]

我现在得到的错误是
ArgumentError:notregisted:features
以这种方式生成工厂对象是不明智的,还是我遗漏了什么?非常感谢您的所有意见

创建这些类型的关联需要使用FactoryGirl的回调

这里可以找到一组完美的例子

把它带到你的例子中

Factory.define :listing_with_features, :parent => :listing do |listing|
  listing.after_create { |l| Factory(:feature, :listing => l)  }
  #or some for loop to generate X features
end

或者,您可以使用块并跳过
关联
关键字。这样就可以在不保存到数据库的情况下构建对象(否则,即使使用
build
功能而不是
create
,许多关联也会将记录保存到数据库)


我尝试了几种不同的方法,这是对我来说最可靠的方法(适合您的情况)


以下是我如何设置我的:

# Model 1 PreferenceSet
class PreferenceSet < ActiveRecord::Base
  belongs_to :user
  has_many :preferences, dependent: :destroy
end

#Model 2 Preference

class Preference < ActiveRecord::Base    
  belongs_to :preference_set
end



# factories/preference_set.rb

FactoryGirl.define do
  factory :preference_set do
    user factory: :user
    filter_name "market, filter_structure"

    factory :preference_set_with_preferences do
      after(:create) do |preference|
        create(:preference, preference_set: preference)
        create(:filter_structure_preference, preference_set: preference)
      end
    end
  end

end

# factories/preference.rb

FactoryGirl.define do
  factory :preference do |p|
    filter_name "market"
    filter_value "12"
  end

  factory :filter_structure_preference, parent: :preference do
    filter_name "structure"
    filter_value "7"
  end
end

希望有帮助。

您可以使用trait:

FactoryGirl.define do
  factory :listing do
    ...

    trait :with_features do
      features { build_list :feature, 3 }
    end
  end
end
使用
回调
,如果需要创建数据库:

...

trait :with_features do
  after(:create) do |listing|
    create_list(:feature, 3, listing: listing)
  end
end
在您的规格中使用如下:

let(:listing) { create(:listing, :with_features) }
这将消除工厂中的重复,并且更易于重用


您是否使用了association:features、[:factory=>:feature]?这是猫咪的叫声。
构建
创建
的能力使其成为最通用的模式。然后使用此自定义FG构建策略为发布嵌套的属性,当测试控制器操作时,
接受
的嵌套的关联关键字对父级和子级使用相同的构建策略。因此,它可以构建不保存到数据库的对象。
# Model 1 PreferenceSet
class PreferenceSet < ActiveRecord::Base
  belongs_to :user
  has_many :preferences, dependent: :destroy
end

#Model 2 Preference

class Preference < ActiveRecord::Base    
  belongs_to :preference_set
end



# factories/preference_set.rb

FactoryGirl.define do
  factory :preference_set do
    user factory: :user
    filter_name "market, filter_structure"

    factory :preference_set_with_preferences do
      after(:create) do |preference|
        create(:preference, preference_set: preference)
        create(:filter_structure_preference, preference_set: preference)
      end
    end
  end

end

# factories/preference.rb

FactoryGirl.define do
  factory :preference do |p|
    filter_name "market"
    filter_value "12"
  end

  factory :filter_structure_preference, parent: :preference do
    filter_name "structure"
    filter_value "7"
  end
end
@preference_set = FactoryGirl.create(:preference_set_with_preferences)
FactoryGirl.define do
  factory :listing do
    ...

    trait :with_features do
      features { build_list :feature, 3 }
    end
  end
end
...

trait :with_features do
  after(:create) do |listing|
    create_list(:feature, 3, listing: listing)
  end
end
let(:listing) { create(:listing, :with_features) }