瘦身多态控制器;逻辑属于哪里?

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

你说得对,没有理由复制那种东西。这种东西可以放在三个地方中的任何一个(假设它只在一个控制器中使用):

  1. 在同一控制器的私有方法中。您可以从每个操作调用该方法,或在 before_action

  2. 中列出需要它的操作
  3. 在该控制器的帮助程序中,使用一种接受参数[:vote] 和 returns votable 的方法。

  4. 在 app/models 或您自己的 app/whatever 目录中创建一个普通的 ruby class,方法类似于辅助方法。当您有多个这样的方法时,这通常更有意义,并且您想要一个比助手更面向对象的解决方案。