Ответ 1
Вы можете попробовать что-то вроде этого:
(Factory.build :code).attributes.symbolize_keys
Отметьте это: http://groups.google.com/group/factory_girl/browse_thread/thread/a95071d66d97987e)
У меня есть модель кода factory следующим образом:
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.
[email protected]:~/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"}
Любые идеи?
Спасибо,
Вы можете попробовать что-то вроде этого:
(Factory.build :code).attributes.symbolize_keys
Отметьте это: http://groups.google.com/group/factory_girl/browse_thread/thread/a95071d66d97987e)
Это не возвращает метки времени и т.д., только атрибуты, доступные для массового присвоения:
(FactoryGirl.build :position).attributes.symbolize_keys.reject { |key, value| !Position.attr_accessible[:default].collect { |attribute| attribute.to_sym }.include?(key) }
Тем не менее, это довольно уродливо. Я думаю, FactoryGirl должен предоставить что-то подобное из коробки.
Я открыл запрос для этого здесь.
Я бы предложил еще один подход, который я считаю более ясным:
attr = attributes_for(:code).merge(code_type: create(:code_type))
вот что я делаю...
conf = FactoryGirl.build(:conference)
post :create, {:conference => conf.attributes.slice(*conf.class.accessible_attributes) }
Я синтезировал то, что говорили другие, в случае, если это помогает кому-то еще. Чтобы соответствовать версии FactoryGirl, я использовал Factory.build() вместо FactoryGirl.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
В моем APP/spec/controller/pages_controllers_spec.rb я установил:
let(:valid_attributes) { FactoryGirl.attributes_for(:page).merge(subject: FactoryGirl.create(:theme), user: FactoryGirl.create(:user)) }
Потому что у меня две связанные модели. Это тоже работает:
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
Здесь другой путь. Вероятно, вы хотите опустить атрибуты id
, created_at
и updated_at
.
FactoryGirl.build(:car).attributes.except('id', 'created_at', 'updated_at').symbolize_keys
Ограничения:
create
, как в association :user, strategy: :create
. Эта стратегия может сделать ваш factory очень медленным, если вы не используете его с умом.