FactoryGirl:attributes_for没有给我相关的属性

时间:2011-02-24 10:48:57

标签: ruby-on-rails ruby-on-rails-3 factory-bot

我有一个这样的代码模型工厂:

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"}

有什么想法吗?

谢谢,

7 个答案:

答案 0 :(得分:23)

您可以尝试这样的事情:

(Factory.build :code).attributes.symbolize_keys 

检查:http://groups.google.com/group/factory_girl/browse_thread/thread/a95071d66d97987e

答案 1 :(得分:9)

这个不返回时间戳等,只返回可用于批量分配的属性:

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

但是,这很难看。我认为FactoryGirl应该开箱即用。

我打开了对此here的请求。

答案 2 :(得分:9)

我建议采用另一种方法,我认为更清楚:

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

答案 3 :(得分:2)

继承人我最终做的事情......

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

答案 4 :(得分:2)

我已经合成了其他人所说的内容,以防它帮助其他人。为了与有问题的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

答案 5 :(得分:0)

在我的APP / spec / controllers / 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

答案 6 :(得分:0)

这是另一种方式。您可能希望省略idcreated_atupdated_at属性。

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

限制:

  • 它不会为HMT和HABTM关联生成属性(因为这些关联存储在连接表中,而不是实际属性中)。
  • 工厂中的关联策略必须为create,与association :user, strategy: :create中一样。如果您不明智地使用它,这种策略可能会使您的工厂变得非常慢。