2017-01-03 24 views
1

在我的Rails应用程序创建新文章时,我需要一个UsersCategories的列表,以便为某些下拉列表选择一个类别和作者。从Helper获取数据或在Rails中使用模型

目前我做这个控制器:

def new 
    @article = Article.new 
    @categories = Category.order('title asc').collect { |t| [t.title, t.id] } 
    @users = User.order('email asc').collect { |t| [t.email, t.id] } 
end 

然后在视图:

<%= f.select :category_id, options_for_select(@categories), :prompt => '-- Please Select --', :required => true %> 

但根据RubyDocs这是不好的做法,这不是很干,因为我那么有编辑方法也是这样做的。为了防止这种情况,我有两个可能的选择,我能想到的:

1)使用这样的帮手:

def users_for_select 
    User.order('email asc').collect { |t| [t.email, t.id] } 
end 

def categories_for_select 
    Category.order('title asc').collect { |t| [t.title, t.id] } 
end 

然后在视图:

<%= f.select :category_id, options_for_select(categories_for_select), :prompt => '-- Please Select --', :required => true %> 

2)它移动到一个型号:

def self.categories_for_select 
    Category.order('title asc').collect { |t| [t.title, t.id] } 
end 

def self.users_for_select 
    User.order('email asc').collect { |t| [t.email, t.id] } 
end 

然后在控制器做到这一点:

def new 
    @article = Article.new 
    @categories = Category.categories_for_select 
    @users = User.users_for_select 
end 

选项1感觉更清洁,因为它从控制器中删除了代码,但我的印象是选项2会更好,因为它使用数据模型(按预期)并且控制器仍在发送数据(如预期的那样)但更干。

我觉得自己是助手和模型获取数据之间有时也会出现一些重叠。

+0

..而又一个选择 - 作为两者之间的一种 - 是装饰者模式 - https://github.com/drapergem/draper。这个逻辑太过于关注于你的模型。话虽如此,过去我只是使用你描述的帮助者方法。 –

+0

选项1比选项2好得多,不仅DRY,而且Model类也应该尊重SRP。 –

回答

2

我将与(1)你的helper方法去了。这很简单直接。正如我在评论中所说的,如果您对选项(2)进行了尝试,则可以在模型周围使用装饰器(例如,使用draper)添加我认为相当特定于视图的逻辑。

一个注意你的helper方法 - 使用pluck,而不是collect所以你不选择列或实例一堆不需要的对象。

此外,order defaults to asc,这样可以缩短整个事情:

def users_for_select 
    User.order(:email).pluck(:email, :id) 
end 
1

我会用一个辅助方法是:

# in a helper 
def category_options_for_select 
    options_for_select(Category.order(:title).pluck(:title, :id)) 
end 

# in the view 
<%= f.select :category_id, category_options_for_select, prompt: '-- Please Select --', required: true %> 
1

我会亲自去与选项1

当然,你可以把它放在你的模型中。你迟早会发现,这将是扩大模型的好方法。那么你可能会考虑使用担忧来掩盖臃肿。而这个混乱的趋势还在继续。

这就是为什么我认为选项1更好。即使你没有创建一个单独的类来处理格式化,你仍然可以将功能抽象为一个更容易缩放的小部分。当然,组合胜过继承。

Bryany的awesome post为耐火材料模型提供了很多选择。

正如@damien在他的回答中已经指出的,您将要使用ActiveRecord的pluck而不是ruby的collectPluck查询数据库,以便它仅返回所需的对象。

相关问题