【问题标题】:Voting in voter controller for multiple models passing polymorphic/duck typed object variable在投票者控制器中为传递多态/鸭子类型对象变量的多个模型投票
【发布时间】:2014-06-12 11:15:08
【问题描述】:

我正在尝试为各种模型实施投票:角色模型、宇宙模型。我通过单个 DRY 渲染部分在他们各自的节目模板上有一些投票按钮。这意味着当我将该模型传递给创建投票记录的控制器逻辑时,我需要使该模型的部分不可知。

所以是的,我想知道是否可以将这种鸭子类型的变量传递给投票控制器,而不是在每个角色和宇宙控制器中重复投票创建逻辑。

如何使用路径助手、部分投票和投票控制器进行这种鸭子类型变量传递?还是应该在每个可投票模型中重复代码?

仅供参考:当然,这两个模型的投票是多态的。我正在使用acts_as_votable gem https://github.com/ryanto/acts_as_votable

_vote.html.haml

.vote-comment-buttons
  = link_to image_tag("upvote.png"), votes_upvote_path(), method: :post, remote: true
  %span=# @comment.get_upvotes.sum(:vote_weight)
  = link_to image_tag("downvote.png"), votes_downvote_path(), method: :post, remote: true

^ 我是否将鸭子类型变量传递给路径?如果是,我如何/在哪里定义鸭子类型变量?

(注意:我正在尝试通过 AJAX 投票,但请随意忽略与 ajax 相关的代码,例如 remote: true)

character.rb

class Character < ActiveRecord::Base
  acts_as_votable # creates a polymorphic association with votes
end

universe.rb

class Universe < ActiveRecord::Base
  acts_as_votable # creates a polymorphic association with votes
end

votes_controller.rb

class VotesController < ApplicationController

  before_action :check_if_voted(@votable)

  def upvote
    #votable.vote_up current_user

  end

  def downvote(votable)
    #votable.vote_down current_user
  end
end

在动作上有参数是否有效?还是只使用 params[]?

【问题讨论】:

    标签: ruby-on-rails helper polymorphism


    【解决方案1】:

    在动作上有参数是否有效?还是你只是使用 参数[]?

    公共动作不能有参数,所有数据都应该从params[]解析

    如何使这种鸭子类型的变量使用路径传递 助手、部分投票和投票控制器?或者我应该只是 在每个可投票模型中重复代码?

    假设两种模型的投票程序相同,请考虑使用concerns

    config/application.rb

     module YourApplicationName
       class Application < Rails::Application
         config.autoload_paths += %W(#{config.root}/app/controllers/concerns)
       end
     end
    

    app/controllers/concerns/voting_controller.rb

    module VotingController
      extend ActiveSupport::Concern
    
      included do
        before_filter :obtain_resources, only: [:upvote, :downvote]
      end
    
      def upvote
        # here goes your upvoting logics, something like
        # @object.liked_by user1, :vote_weight => 1
        # the @object variable has already been set in obtain_resource filter
        # other params should be catched up from the params hash
      end
    
      def downvote
        # here goes your downvoting logics
      end
    
      private
      def obtain_resources
        # here we retrieve the name of a particular controller which triggered this action
        model = controller_name.singularize.camelize.constantize
        @object = model.find(params[:id])
      end
    end
    

    如果您更喜欢使用有意义的变量名而不仅仅是@object,您可以这样做:

    # app/controllers/concerns/voting_controller.rb
    def obtain_resources
      model = controller_name.singularize.camelize.constantize
      instance_name = controller_name.singularize
      # here you get @universe or @character
      instance_variable_set "@#{instance_name}", model.find(params[:id])
    end
    

    那么你应该在你的控制器中包含这个问题:

    class UniverseController < ApplicationController
      include VotingController
      # that's all, you should not implement voting actions here as they are included from VotingController
    end
    
    class CharactersController < ApplicationController
      include VotingController
    end
    

    您还应该确保在 config/routes.rb 文件中设置适当的路由,以便 upvotedownvote 操作存在于 both 中控制器。正如您已经理解的那样,您应该将upvote_universe_pathupvote_characters_path 传递给您的部分以使其工作(对于downvoting 也是如此)。每个路由都应该将对象的id 传递给控制器​​的操作。

    【讨论】:

    • 问题:我正在使用acts_as_votable gem,它有自己的控制器,gem 文件中的迁移。虽然我看到了使用模块控制器的美妙之处,但创建第二个控制器将是多余的,并且可能会产生问题以使事物正常运行。
    • 嗯,有很多线程和资源讨论如何以最佳方式学习 Rails(只需在 google 中查看)。至于个人建议,请看codeschool.com。他们有很多关于 ruby​​/rails 的初级和中级课程。
    • 你确定acts_of_votable gem 中的控制器动作吗?据我从documentation 和源代码中看到的,它只是将一些方法附加到您的模型中,因此控制器部分应该单独完成。
    • 我有很好的概念知识,可以分解需要填充的部分。但是句法知识和经验阻碍了我。我觉得我已经为中级到高级的东西做好了准备,只要有好的文档,或者如果我获得了更好地阅读源代码的加速能力。我会检查控制器的东西。我已经从你的例子中学到了很多东西。控制器关注点,从控制器等各种轨道位置获取字符串...
    • @gwho instance_variable_setObject 的一个方法。应该适用于 Ruby 1.9 和 2.1。看看this api page
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-09
    • 2018-07-28
    • 1970-01-01
    相关资源
    最近更新 更多