在我的rails模型中,我定义了一个类和一个方法来返回一个Project名称数组。现在我的问题是,如果我在我的视图中使用Project.names数组是正确的,或者我应该在控制器中生成一个数组,并传递一个实例变量。
class Project < ActiveRecord::Base
...snip...
def self.names
Project.select(:name).map {|x| x.name }
end
end
答案 0 :(得分:2)
我肯定会坚持在控制器中填充实例变量。 BTW,关于你的代码的一句话:
Project.select(:name).map {|x| x.name }
可以重构为:
Project.select(:name).map(&:name)
这个,可以重构为:
Project.pluck(:name)
爱红宝石。
答案 1 :(得分:1)
通常认为最佳做法是将数据的提取和数据的显示分开,视图只负责显示数据。我肯定会说在控制器中生成数组并将其传递给您的视图会更好。
MVC是一个非常大的主题 - 有关更多信息,请查看Rails指南:http://guides.rubyonrails.org/getting_started.html
答案 2 :(得分:1)
从实际角度来看,在视图层和控制器逻辑之间划分界限始终是一个艰难的决定。用以下内容填充控制器可能会有问题:
# controller
@project_names = Project.names
# view
<%= @project_names.join(", ") %>
仅在视图中使用@procject_names
。
但是将这些代码保留在视图中会让您稍后有机会在不更改视图的情况下执行此操作:
# Controller is updated
@project_names = Project.names
# Show only matching projects
if params[:search]
@project_names = @project_names.select{|n| n =~ /#{params[:search]}/}
end
# view - still the same
<%= @project_names.join(", ") %>
另外,请查看构建于其上的Draper gem Decorator pattern模式的MVVM和 ViewModel 。
使用Draper,你可以保持你的控制器更清洁,并根据需要为同一个对象设置多个装饰器(例如一个用于web,另一个用于邮件),同时仍然使用相同的视图代码以呈现输出。
在Decorator中常见的是本地化日期,它取决于登录用户,因此不适合视图,但会使视图层逻辑混乱控制器。