在我的 rails 模型中,我定义了一个类和一个方法来返回一个项目名称数组。现在我的问题是,我应该在我的视图中使用 Project.names 数组是否正确,或者我应该在控制器中生成一个数组并传递一个实例变量。
class Project < ActiveRecord::Base
...snip...
def self.names
Project.select(:name).map {|x| x.name }
end
end
在我的 rails 模型中,我定义了一个类和一个方法来返回一个项目名称数组。现在我的问题是,我应该在我的视图中使用 Project.names 数组是否正确,或者我应该在控制器中生成一个数组并传递一个实例变量。
class Project < ActiveRecord::Base
...snip...
def self.names
Project.select(:name).map {|x| x.name }
end
end
我一定会坚持在控制器中填充实例变量。顺便说一句,关于您的代码:
Project.select(:name).map {|x| x.name }
可以重构为:
Project.select(:name).map(&:name)
这个,可以重构为:
Project.pluck(:name)
爱鲁比。
从实际的角度来看,在视图层和控制器逻辑之间划清界限始终是一个艰难的决定。用以下内容填充您的控制器可能是有问题的:
# 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(", ") %>
另外,看看基于 装饰器模式和MVVM模式的ViewModel的Draper gem 。
使用 Draper,您甚至可以使您的控制器保持清洁,并根据需要为同一对象使用多个装饰器(例如,一个用于 Web,另一个用于邮件程序),同时仍使用相同的视图代码来呈现输出。
放置在装饰器中的常见事情是本地化日期,这取决于登录用户,因此不适合视图,但会使控制器与视图层逻辑混乱。
通常认为最佳实践是将数据的拉取和数据的显示适当地分开,其中视图仅负责显示该数据。我肯定会说在控制器中生成数组并将其传递给您的视图会是一个更好的主意。
MVC 是一个相当大的话题 - 有关更多信息,请查看 Rails 指南: http: //guides.rubyonrails.org/getting_started.html