Дополнительные аргументы для Factory Girl - PullRequest
22 голосов
/ 19 апреля 2010

Мне нужно передать дополнительные аргументы фабричной девушке для использования в обратном вызове. Примерно так (но на самом деле сложнее):

Factory.define :blog do |blog|
  blog.name "Blah"

  blog.after_create do |blog|
    blog.posts += sample_posts
    blog.save!
  end
end

, а затем создайте его следующим образом:

Factory.create(:blog, :sample_posts => [post1, post2])

Есть идеи как это сделать?

Ответы [ 5 ]

32 голосов
/ 16 февраля 2012

Теперь это возможно без каких-либо "взломов" благодаря переходным атрибутам ( см. Комментарий к проблеме # 49 )

пример:

FactoryGirl.define do
  factory :user do
    transient do
      bar_extension false
    end
    name {"foo #{' bar' if bar_extension}"}
  end
end

# Factory(:user).name = "foo"
# Factory(:user, :bar_extension => true).name = "foo bar"

Для версий Factory Girl <5.0: </p>

FactoryGirl.define do
  factory :user do
    ignore do
      bar_extension false
    end
    name {"foo #{' bar' if bar_extension}"}
  end
end

# Factory(:user).name = "foo"
# Factory(:user, :bar_extension => true).name = "foo bar"
2 голосов
/ 20 апреля 2010

По-видимому, в настоящее время это невозможно без обходных путей, которые требуют изменения самой модели. Эта ошибка сообщается в: http://github.com/thoughtbot/factory_girl/issues#issue/49

2 голосов
/ 19 апреля 2010

Одним из вариантов будет создание виртуального средства доступа для дополнительных сообщений, которые проверяет хук after_create:

class Blog
  has_many :posts
  attr_accessible :name, :title, ... # DB columns
  attr_accessor   :sample_posts      # virtual column
end

Factory.define :blog do |blog|
  blog.name 'Blah'

  blog.after_create do |b|
    b.posts += b.sample_posts
    b.save!
  end
end

Factory(:blog, :sample_posts => [post1, post2])
1 голос
/ 20 марта 2012

если вы открываете класс внутри файла factorygirl, я предлагаю сделать это как

require "user"
class User
  attr :post_count
end

так что вы открываете класс, а не перезаписываете его

1 голос
/ 19 апреля 2010

Другой вариант - использовать build вместо create и добавить :autosave в коллекцию:

class Blog
  has_many :posts, :autosave => true
end

Factory.define :blog do |blog|
  blog.name 'Blah'
  blog.posts { |_| [Factory.build(:post)] }
end

Factory(:blog, :posts => [post1, post2])
#or
Factory.build(:blog, :posts => [unsavedPost1, unsavedPost2])
...