我正在尝试为各种模型实施投票:角色,宇宙模型。我通过单个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 []?
答案 0 :(得分:1)
在动作上有参数是否有效?或者你只是使用 PARAMS []?
您不能在公共行动中拥有参数,所有数据都应该从params []
解析如何使用path传递这种类型的duck类型变量 助手,投票局部分和投票控制员?或者我应该 重复每个可投票模型中的代码?
假设两个模型的投票程序相同,请考虑使用concerns:
<强>配置/ application.rb中强>
module YourApplicationName
class Application < Rails::Application
config.autoload_paths += %W(#{config.root}/app/controllers/concerns)
end
end
应用/控制器/关切/ 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 文件中设置适当的路线,以便中存在upvote
和downvote
次操作强大的控制器。正如您已经了解的那样,您应该将upvote_universe_path
或upvote_characters_path
传递给您的部分以使其工作(对于downvoting来说相同)。每条路线都应该将对象的id
传递给控制器的动作。