我正在使用 rails 构建一个 REST API,并且我有一些接受嵌套和递归 JSON 的控制器,例如,在 /taxonomies/:id.json 上执行 PUT 时,您可以传递如下内容:
{
"names":[
"brands",
"secondary_brands"
],
"taxonomy_data":{
"some":"data"
},
"terms":[
{
"slug":"apple",
"data":{
"value":"Apple California"
},
"overridable_data":{
"weight":0.5
},
"term_data":{
"description":{
"en":"Apple makes the iPhone"
}
}
},
{
"slug":"microsoft",
"data":{
"value":"Microsoft Inc"
},
"overridable_data":{
"weight":0.5
},
"term_data":{
"description":{
"en":"Microsoft makes windows"
}
},
"children":[
{
"data":{
"value":"Xbox"
},
"overridable_data":{
"weight":0.5
},
"term_data":{
"description":{
"en":"Xbox one is bad"
}
}
}
]
},
{
"slug":"hp",
"data":{
"value":"HP Inc"
},
"overridable_data":{
"weight":0.5
},
"term_data":{
"description":{
"en":"HP makes atomic clocks"
}
}
}
]
}
现在,我将以下代码放入我的模型中:
class Taxonomy < ActiveRecord::Base
has_many :terms,
-> {order(:id)}
def update_terms(params)
existing_term_ids = terms.map &:id
create_term = lambda do |term_params, parent=nil|
t = terms.find_by(:id => term_params[:id]) if term_params[:id]
t ||= terms.build
t.attributes = term_params.slice(:slug, :data, :overridable_data, :term_data)
t.parent = parent
t.save
existing_term_ids.delete(t.id)
if term_params.has_key?(:children)
term_params[:children].each do |child_params|
create_term.call(child_params, t)
end
end
end
params.each do |term_params|
create_term.call(term_params)
end
terms.where(:id => existing_term_ids).destroy_all
save
end
end
这个版本(快速写入测试 rails 4)使用 slice 来过滤参数,因为 attr_accessible 已经消失了。
这让我想知道这种代码是否应该在模型或控制器中。