我想将params集合从控制器传递给模型以解析过滤和排序条件。在模型中有一个从控制器获取参数的方法是否会破坏MVC?
答案 0 :(得分:4)
这取决于。您正在将数据哈希传递给模型并说“理解这一点”。
class Model < ActiveRecord::Base
def update_from_params(params)
....
end
end
class ModelsController < ActionController::Base
def update
...
@model.update_from_params(params)
end
end
这没关系。但是你可能会发现自己想从许多不同的行动中做到这一点。在每种情况下,您都不太可能使params完全相同,因此您需要在模型上使用多种方法,每种方法对应一种方法:
class Model < ActiveRecord::Base
def update_from_update_params(params)
# do stuff
end
def update_from_settings_params(params)
# do different stuff
end
end
class ModelsController < ActionController::Base
def update
...
@model.update_from_update_params(params)
end
def change_settings
...
@model.update_from_settings_params(params)
end
end
这不行,你正在使模型做控制器工作。一个合理的中途是在模型上创建一个接受规范数据哈希的方法,然后在控制器中的params和规范哈希之间进行转换:
class Model < ActiveRecord::Base
def update_from_data(hash)
validate_data!(hash)
# do stuff
end
end
class ModelsController < ActionController::Base
def update
...
@model.update_from_data(translate_update_params)
end
def change_settings
...
@model.update_from_data(translate_change_settings_params)
end
end
虽然您应该确保仔细记录模型接受的数据哈希的格式。我们实际上甚至使用YAML验证库(Rx)来确保模型只接受有效数据。
很抱歉答案很长,但我没有时间写一篇较短的答案;)。
答案 1 :(得分:1)
我肯定会这样说。
params哈希有许多你的模型不应该需要的东西。基本上你忽略了MVC的C部分。你想做的事情会起作用(也就是说它会执行)但是我认为你应该将参数作为单独的实体传递。
答案 2 :(得分:1)
我建议传递一个params子集,这样你就只传递了模型所需要的东西。
在控制器中:
# in controller
def search
Model.search(params[:search][:options])
end
只需确保您的输入是“命名空间”,这样您就可以获得嵌套哈希:
<!-- in view -->
<input type='text' name='search[options][keywords]' />
<input type='text' name='search[options][conditions]' />
<input type='text' name='search[options][sort]' />
然后在你的模型中:
def self.do_search(criteria)
Rental.search(criteria[:keywords],
:per_page => self.per_page,
:page => page,
:conditions => criteria[:conditions],
:order => criteria[:sort])
end
答案 3 :(得分:0)
我不相信,但是我再也不是铁杆老兵了。通常,params散列在控制器中使用,并且该动作可能会也可能不会读取和写入模型信息,所以我想如果params要通过属于模型的方法,那将是同样的事情。
无论哪种方式,我认为您仍然需要通过控制器发送参数,那么为什么不在那里进行处理,然后通过模型的方法将处理后的数据发送到模型?