瘦身多态控制器;逻辑属于哪里?
Slimming down polymorphic controller; where does the logic belong?
我正在实施自己的 RESTful 投票系统。 'Questions' 和 'Answers' 都是可投票的。创建、更新和删除投票。
当对可投票对象执行操作时,可投票对象的 class 作为参数传递。控制器需要查看 votable_type 以检索正确的可投票对象,以便将其传递给部分对象。
目前我的votes_controller中有这个逻辑:
if params[:vote][:votable_type] == 'Question'
@votable = Question.find(params[:vote][:votable_id])
elsif params[:vote][:votable_type] == 'Answer'
@votable = Answer.find(params[:vote][:votable_id])
end
它在每个控制器动作中都是重复的。 它真正属于哪里?我怎样才能干掉这个控制器?
更新:这是我的投票按钮:
<%= link_to "", votes_path(vote: {
votable: votable,
votable_type: votable.class,
votable_id: votable.id,
value: "upvote"
}),
method: :post,
remote: :true,
class: "upvote" %>
@vote = Vote.find(:id) #it depends of what is your params[:vote]
@votable = @vote.votable # it will return parent of your vote
http://guides.rubyonrails.org/association_basics.html#polymorphic-associations
您可以将以上代码包装在私有方法中,然后在您的操作中使用它,即:
....
def update
votable.update(...)
end
private
def votable
@votable ||= Vote.find(:id).votable
end
你说得对,没有理由复制那种东西。这种东西可以放在三个地方中的任何一个(假设它只在一个控制器中使用):
在同一控制器的私有方法中。您可以从每个操作调用该方法,或在 before_action
中列出需要它的操作
在该控制器的帮助程序中,使用一种接受参数[:vote] 和 returns votable 的方法。
在 app/models 或您自己的 app/whatever 目录中创建一个普通的 ruby class,方法类似于辅助方法。当您有多个这样的方法时,这通常更有意义,并且您想要一个比助手更面向对象的解决方案。
我正在实施自己的 RESTful 投票系统。 'Questions' 和 'Answers' 都是可投票的。创建、更新和删除投票。
当对可投票对象执行操作时,可投票对象的 class 作为参数传递。控制器需要查看 votable_type 以检索正确的可投票对象,以便将其传递给部分对象。
目前我的votes_controller中有这个逻辑:
if params[:vote][:votable_type] == 'Question'
@votable = Question.find(params[:vote][:votable_id])
elsif params[:vote][:votable_type] == 'Answer'
@votable = Answer.find(params[:vote][:votable_id])
end
它在每个控制器动作中都是重复的。 它真正属于哪里?我怎样才能干掉这个控制器?
更新:这是我的投票按钮:
<%= link_to "", votes_path(vote: {
votable: votable,
votable_type: votable.class,
votable_id: votable.id,
value: "upvote"
}),
method: :post,
remote: :true,
class: "upvote" %>
@vote = Vote.find(:id) #it depends of what is your params[:vote]
@votable = @vote.votable # it will return parent of your vote
http://guides.rubyonrails.org/association_basics.html#polymorphic-associations
您可以将以上代码包装在私有方法中,然后在您的操作中使用它,即:
....
def update
votable.update(...)
end
private
def votable
@votable ||= Vote.find(:id).votable
end
你说得对,没有理由复制那种东西。这种东西可以放在三个地方中的任何一个(假设它只在一个控制器中使用):
在同一控制器的私有方法中。您可以从每个操作调用该方法,或在 before_action
中列出需要它的操作
在该控制器的帮助程序中,使用一种接受参数[:vote] 和 returns votable 的方法。
在 app/models 或您自己的 app/whatever 目录中创建一个普通的 ruby class,方法类似于辅助方法。当您有多个这样的方法时,这通常更有意义,并且您想要一个比助手更面向对象的解决方案。