创建“多态”控制器

时间:2015-12-21 05:01:20

标签: ruby-on-rails

我正在努力为我的应用添加投票(例如在Stackoveflow中)。我有两个模型问题和答案,所以我希望能够投票给他们两个。我看到两种管理不同类型模型投票的方法:

  1. 增加对模型,控制器和路线的关注。
  2. 添加投票控制器,可以处理任何已投票的模型的投票。
  3. 我想用第二种方法来解决我的问题。但是要使用控制器,我应该将两个参数传递给控制器​​,例如:votable_type:model-name,votable-id:object.id,我的路线看起来像:vote_up_vote_path,vote_down_vote_path。

    有没有办法使用如下路线:vote_up_path(answer); vote_down_path(问题)?

    通过传递对象“vote_up_path (回答)”我希望能够在控制器中获取

    P.S。我无法使用宝石。宝石为模型提供逻辑,我已经有了这个逻辑。

    我找到了解决方案。所以首先我们需要生成投票控制器。

    $rg controller Votes
    

    比我们添加路线:

    resource :vote, only: [:vote_up, :vote_down, :unvote] do
        patch :vote_up, on: :member
        patch :vote_down, on: :member
        patch :unvote, on: :member
    end
    

    并加入votes_helper.rb:

    module VotesHelper
      def  vote_up_path(votable)
        {controller: "votes", action: "vote_up",
         votable_id: votable.id, votable_type: votable.class}
      end
    
      def  vote_down_path(votable)
        {controller: "votes", action: "vote_down",
         votable_id: votable.id, votable_type: votable.class}
      end
    
      def  unvote_path(votable)
        {controller: "votes", action: "unvote",
         votable_id: votable.id, votable_type: votable.class}
      end
    end
    

    我们应该添加测试并完成我们的方法。在控制器中,我们可以使用此方法查找我们的可投票:

    private
    
      def set_votable
        klass = params[:votable_type].to_s.capitalize.constantize
        @votable = klass.find(params[:votable_id])
      end
    

1 个答案:

答案 0 :(得分:0)

强烈建议使用此宝石来处理upvote / downvote:

Acts as votable