带有has_many的模型规范:through;如何让它工作?

时间:2014-01-20 09:04:12

标签: ruby-on-rails rspec ruby-on-rails-4 factory-bot

我的活动和客户之间的关系称为“Activityclient”(原创,是吗?)

每当我尝试通过FactoryGirl规范我的Activity.rb时,我得到

 1) Activity has valid factory
    Failure/Error: expect(FactoryGirl.build(:activity)).to be_valid
    NoMethodError:
      undefined method `stringify_keys' for #<Activityclient:0x73498b0>
    # ./app/models/activity.rb:52:in `block in activityclients='
    # ./app/models/activity.rb:48:in `each'
    # ./app/models/activity.rb:48:in `activityclients='
    # C:in `object'
    # ./spec/models/activity_spec.rb:5:in `block (2 levels) in <top (required)>

我的活动工厂是:

FactoryGirl.define do
    factory :activity do
        title { "Activity" }
        group_id { "1" }
        url { "http://www.abc.com/"} 
        activityclients {[FactoryGirl.create(:activityclient)]}
        client {FactoryGirl.create(:client)}
    end
end

我的Activityclient工厂:

FactoryGirl.define do
    factory :activityclient do
        start_date {Date.parse('2013-05-13 12:00:00')}
        end_date {Date.parse('2013-05-13 12:15:00')}
        group_id { 1 }
    end
end

我做错了什么?

提前致谢,

编辑:@ Vee的建议后编辑。同样的错误

1 个答案:

答案 0 :(得分:0)

某些“应该是”属性被视为activityactivityclient工厂中的方法。

使用以下内容更新activity工厂:

FactoryGirl.define do
    factory :activity do
        title { "Activity" }
        group_id { "1" }
        url { "http://www.abc.com/"} 
        activityclients {[FactoryGirl.create(:activityclient)]}
        client {FactoryGirl.create(:client)}
    end
end

请注意titlegroup_idurl是如何使用{...}设置的。同时确保activityclient属性group_id工厂中的相同内容:

FactoryGirl.define do
    factory :activityclient do
        start_date {Date.parse('2013-05-13 12:00:00')}
        end_date {Date.parse('2013-05-13 12:15:00')}
        group_id { 1 }
    end
end

其他一些建议:

当你在工厂女孩工厂内时(相反,当需要factory_girl时)你不需要拼出FactoryGirl.create,你可以打电话给create。其次,而不是提供Date.parse提供timepart,因为你正在使用Date类,所以会被忽略。您应该使用TimeDateTime

这些工厂看起来如下(注意以下示例使用DateTime,如果您愿意,可以使用Time

# activity
FactoryGirl.define do
    factory :activity do
        title { "Activity" }
        group_id { 1 }
        url { "http://www.abc.com/"} 
        activityclients { [ create(:activityclient) ] }
        client { create(:client) }
    end
end

#activityclient
FactoryGirl.define do
    factory :activityclient do
        start_date { DateTime.now.midnight }
        end_date { DateTime.now.midnight.change(min: 15) }
        group_id { 1 }
    end
end

为确保正确设置关联,请更新工厂定义以使用callbacks

# activity
FactoryGirl.define do
    factory :activity do
        title { "Activity" }
        group_id { 1 }
        url { "http://www.abc.com/"} 

        after(:create) do |a|
          a.activityclients << create(:activityclient)
          a.client { create(:client) }
        end
    end
end

另外,使用以下内容将activityclient的分配更新为a.activityclients

a.activityclients << create(:activityclient) 

而不是使用a.activityclients { [ create(:activityclient) ] }指定数组。对于前者,FactoryGirl分配并保存关联,而后者虽然分配了数组,但不保存关联。

更新:

只有在规范中使用after(:create)创建工厂时才会执行FactoryGirl.create...回调。如果您仅使用FactoryGirl.build构建它们,则应将after(:create)替换为after(:build)。有关详细信息,请参阅FactoryGirl callbacks