[英]Properly constructing params from factories with nested associations in rspec controller tests
這是模型關系:
class Tool < ActiveRecord::Base
...
has_many :loss_ratios, :dependent => :destroy, :order => "loss_ratios.starts_at DESC"
validates_associated :loss_ratios
accepts_nested_attributes_for :loss_ratios, :allow_destroy => true
attr_accessible :name, :text, :service_id, :supplier_id, :loss_ratios_attributes
end
class LossRatio < ActiveRecord::Base
belongs_to :tool
validates :rate, :starts_at, :tool, :presence => true
validates_uniqueness_of :starts_at, :scope => :tool_id
validates_numericality_of :rate
validates_inclusion_of :rate, :in => (0..1)
...
end
我正在創建/更新ToolsController動作中管理LossRatio關聯。 我想通過發布工具的屬性集來測試這些屬性(包括幾個嵌套的LossRatio,就像它們是以表單形式提交一樣)。 我正在使用FactoryGirl,但是它似乎沒有構造類似params的屬性哈希的方法(attributes_for忽略關聯,並且看起來這種行為不會改變)。 有沒有辦法做到這一點?
(我知道標題是一團糟,但我想不出更好或更短的東西了……)
好,這是我將頭發拉出半天后想到的:
def params_for(factory_name)
exclude_params = [ "id", "created_at", "updated_at" ]
f = FactoryGirl.build(factory_name)
params = f.attributes.except(*exclude_params).dup
f.reflections.select { |k,v|
v.macro == :has_many && !v.instance_of?(ActiveRecord::Reflection::ThroughReflection)
}.each_key do |k|
assoc_collection = f.send(k)
unless assoc_collection.empty?
params["#{k.to_s}_attributes"] = {}
assoc_collection.each_with_index do |assoc_obj,idx|
params["#{k.to_s}_attributes"][idx.to_s] = assoc_obj.attributes.except(*exclude_params << "#{f.class.name.underscore}_id")
end
end
end
params
end
這是用於構建控制器的CRUD操作可消耗的params哈希的輔助方法。 我在控制器規格中使用它,如下所示:
subject { post :create, :tool => params_for(:tool_with_lr_history) }
it "creates a new tool" do
expect { subject }.to change(Tool, :count).by(1)
end
從片段中可以看出,該方法僅填充has-many關聯的屬性(而忽略has-many-through關聯)。 我想它可能會擴展到任何類型的關系,但是到目前為止對我仍然有效(除非有一種更好的方式來做我想要的事情)...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.