Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 创造;多态性;控制器_Ruby On Rails - Fatal编程技术网

Ruby on rails 创造;多态性;控制器

Ruby on rails 创造;多态性;控制器,ruby-on-rails,Ruby On Rails,我正在将投票添加到我的应用程序中(比如Stackoveflow)。我有两个模型的问题和答案,所以我想能够投票支持这两个模型。我认为有两种方法可以管理不同类型车型的投票: 增加对模型、控制器和管线的关注 添加投票控制器,该控制器可处理任何可投票模型的投票 我想用第二种方法来解决我的问题。但要使用控制器,我应该将两个参数传递给控制器,比如:votable\u type:model name,votable id:object.id,我的路由看起来像:vote\u up\u vote\u path,v

我正在将投票添加到我的应用程序中(比如Stackoveflow)。我有两个模型的问题和答案,所以我想能够投票支持这两个模型。我认为有两种方法可以管理不同类型车型的投票:

  • 增加对模型、控制器和管线的关注
  • 添加投票控制器,该控制器可处理任何可投票模型的投票
  • 我想用第二种方法来解决我的问题。但要使用控制器,我应该将两个参数传递给控制器,比如:votable\u type:model name,votable id:object.id,我的路由看起来像:vote\u up\u vote\u path,vote\u down\u vote\u path

    有没有一种方法可以使用这样的路线:投票沿着路径(答案);投票通过(问题)

    通过传递对象“向上投票路径”(答案),我希望能够在控制器中获得它

    另外,我不会用宝石。Gems为模型提供了逻辑,我已经有了这种逻辑

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

    $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
    
    并添加投票_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
    
    然后我们应该添加测试并完成我们的方法。在控制器中,我们可以使用此方法查找votable:

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

    强烈推荐此创业板处理向上投票/向下投票:


    强烈推荐此创业板处理向上投票/向下投票:


    有两种方法可以做到这一点;第一种是使用超类控制器,第二种是使用带有多态模型的单个控制器

    我将详细介绍这两个方面:


    超分类

    您可以在“超级”控制器中设置方法,该方法将分别由
    答案
    问题
    控制器继承。这有点蹩脚,因为这意味着你正在向
    答案
    问题
    控制器发送请求(这违反了原则):

    这将允许您执行以下操作:

    <%= link_to "Upvote", answers_vote_path(@answer), method: :post %>
    <%= link_to "Downvote", questions_vote_path(@question), method: :delete %>
    
    #config/routes.rb
    resources vote, only: [] do
       match ":voteable_type/:voteable_id", action: :vote, via: [:post,:delete], on: :collection #-> url.com/vote/answer/3
    end
    
    #app/controllers/votes_controller.rb
    class VotesController < ApplicationController
       def vote
         if request.post?
           @vote = Vote.create vote_params
         elsif request.delete?
           @vote = Vote.destroy vote_params
         end
       end
    
       private
    
       def vote_params
         params.permit(:voteable_id, :voteable_type)
       end
    end
    
    <%= link_to "Vote", votes_path(:answer, @answer.id) %>
    
    #config/routes.rb
    资源投票,仅:[]执行
    匹配“:voteable_type/:voteable_id”,action::vote,via:[:post,:delete],on::collection#->url.com/vote/answer/3
    结束
    #app/controllers/vows\u controller.rb
    类VotesController<应用程序控制器
    def投票
    如果请求,请发邮件?
    @投票=投票。创建投票参数
    elsif request.delete?
    @投票=vote.destroy投票参数
    结束
    结束
    私有的
    def vote_params
    参数许可证(:voteable_id,:voteable_type)
    结束
    结束
    
    这将允许您使用以下各项:

    <%= link_to "Upvote", answers_vote_path(@answer), method: :post %>
    <%= link_to "Downvote", questions_vote_path(@question), method: :delete %>
    
    #config/routes.rb
    resources vote, only: [] do
       match ":voteable_type/:voteable_id", action: :vote, via: [:post,:delete], on: :collection #-> url.com/vote/answer/3
    end
    
    #app/controllers/votes_controller.rb
    class VotesController < ApplicationController
       def vote
         if request.post?
           @vote = Vote.create vote_params
         elsif request.delete?
           @vote = Vote.destroy vote_params
         end
       end
    
       private
    
       def vote_params
         params.permit(:voteable_id, :voteable_type)
       end
    end
    
    <%= link_to "Vote", votes_path(:answer, @answer.id) %>
    

    有两种方法可以做到这一点;第一种是使用超类控制器,第二种是使用带有多态模型的单个控制器

    我将详细介绍这两个方面:


    超分类

    您可以在“超级”控制器中设置方法,该方法将分别由
    答案
    问题
    控制器继承。这有点蹩脚,因为这意味着你正在向
    答案
    问题
    控制器发送请求(这违反了原则):

    这将允许您执行以下操作:

    <%= link_to "Upvote", answers_vote_path(@answer), method: :post %>
    <%= link_to "Downvote", questions_vote_path(@question), method: :delete %>
    
    #config/routes.rb
    resources vote, only: [] do
       match ":voteable_type/:voteable_id", action: :vote, via: [:post,:delete], on: :collection #-> url.com/vote/answer/3
    end
    
    #app/controllers/votes_controller.rb
    class VotesController < ApplicationController
       def vote
         if request.post?
           @vote = Vote.create vote_params
         elsif request.delete?
           @vote = Vote.destroy vote_params
         end
       end
    
       private
    
       def vote_params
         params.permit(:voteable_id, :voteable_type)
       end
    end
    
    <%= link_to "Vote", votes_path(:answer, @answer.id) %>
    
    #config/routes.rb
    资源投票,仅:[]执行
    匹配“:voteable_type/:voteable_id”,action::vote,via:[:post,:delete],on::collection#->url.com/vote/answer/3
    结束
    #app/controllers/vows\u controller.rb
    类VotesController<应用程序控制器
    def投票
    如果请求,请发邮件?
    @投票=投票。创建投票参数
    elsif request.delete?
    @投票=vote.destroy投票参数
    结束
    结束
    私有的
    def vote_params
    参数许可证(:voteable_id,:voteable_type)
    结束
    结束
    
    这将允许您使用以下各项:

    <%= link_to "Upvote", answers_vote_path(@answer), method: :post %>
    <%= link_to "Downvote", questions_vote_path(@question), method: :delete %>
    
    #config/routes.rb
    resources vote, only: [] do
       match ":voteable_type/:voteable_id", action: :vote, via: [:post,:delete], on: :collection #-> url.com/vote/answer/3
    end
    
    #app/controllers/votes_controller.rb
    class VotesController < ApplicationController
       def vote
         if request.post?
           @vote = Vote.create vote_params
         elsif request.delete?
           @vote = Vote.destroy vote_params
         end
       end
    
       private
    
       def vote_params
         params.permit(:voteable_id, :voteable_type)
       end
    end
    
    <%= link_to "Vote", votes_path(:answer, @answer.id) %>
    
    
    
    很好,但我不能使用gems。因为是训练任务,所以我应该独立完成这个故事。哦,我明白了。那为什么不使用参数呢?如果我是你,我只会使用一个路径
    vote_path
    ,然后得到三个参数:value(0,1,-1)、votable_type和votable_id。我相信gem也做了类似的事情。可能它满足了所需的任务,但我说的是创建不代表资源的控制器。这是一个可接受的实践吗?看看acts as votable gem lib文件,了解它,您将看到如何做到您所要求的,因为您不允许使用gems。它使用多态关联@Alexandro是的,这很有意义。正如@ollaollu所说的,从宝石中学习会对你有很大帮助。这很好,但我不能使用宝石。因为是训练任务,所以我应该独立完成这个故事。哦,我明白了。那为什么不使用参数呢?如果我是你,我只会使用一个路径
    vote_path
    ,然后得到三个参数:value(0,1,-1)、votable_type和votable_id。我相信gem也做了类似的事情。可能它满足了所需的任务,但我说的是创建不代表资源的控制器。这是一个可接受的实践吗?看看acts as votable gem lib文件,了解它,您将看到如何做到您所要求的,因为您不允许使用gems。它使用多态关联@Alexandro是的,这很有意义。正如@ollaollu所说的,从gem所做的事情中学习将对你有很大帮助。