[英]Voting in voter controller for multiple models passing polymorphic/duck typed object variable
I am trying to implement voting for various models: Character, Universe models. 我正在尝试对各种模型进行投票:角色模型,宇宙模型。 I have some vote buttons on their respective show templates via a single DRY rendered partial.
我通过单个DRY渲染的部分在各自的显示模板上有一些投票按钮。 This means I need to make that partial agnostic to the model when I pass that model to the controller logic that creates the vote record.
这意味着当我将模型传递给创建投票记录的控制器逻辑时,我需要对该模型进行部分不可知的处理。
So yes, I am wondering if it is possible to have this kind of duck typed variable passing to a votes controller, rather than repeating the vote creation logic in each of the Character and Universe controller. 所以是的,我想知道是否有可能将这种鸭子类型的变量传递给投票控制器,而不是在每个Character and Universe控制器中重复投票创建逻辑。
How do I make this sort of duck typed variable passing using path helpers, votes partials, and votes controllers? 如何使用路径助手,投票局部和投票控制器使此类鸭子类型变量传递? Or should I just repeat the code in each votable model?
还是我应该在每个可移植模型中重复代码?
FYI: Naturally, the votes is polymorphic to the two models. 仅供参考:自然,两个模型的投票是多态的。 I am using acts_as_votable gem https://github.com/ryanto/acts_as_votable
我正在使用acts_as_votable gem https://github.com/ryanto/acts_as_votable
_vote.html.haml _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
^ Do I pass a duck type variable to the paths?, If so, how/where do I define the duck type variable? ^是否将鸭子类型变量传递到路径?,如果是,如何/在哪里定义鸭子类型变量?
(Note: i'm trying to vote via AJAX, but feel free to ignore the ajax related code like remote: true) (注意:我正在尝试通过AJAX进行投票,但可以忽略与ajax相关的代码,例如remote:true)
character.rb character.rb
class Character < ActiveRecord::Base
acts_as_votable # creates a polymorphic association with votes
end
universe.rb universe.rb
class Universe < ActiveRecord::Base
acts_as_votable # creates a polymorphic association with votes
end
votes_controller.rb 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
Iis it valid to have parameters on actions? 在动作上设置参数是否有效? or do you just use params[]?
还是只使用params []?
Iis it valid to have parameters on actions?
在动作上设置参数是否有效? or do you just use params[]?
还是只使用params []?
You can not have parameters at public actions, all the data should be parsed from params[] 您不能在公共操作中使用参数,应从params []解析所有数据
How do I make this sort of duck typed variable passing using path helpers, votes partials, and votes controllers?
如何使用路径助手,投票局部和投票控制器使此类鸭子类型变量传递? Or should I just repeat the code in each votable model?
还是我应该在每个可移植模型中重复代码?
Assuming voting procedure is the same for both models, consider using concerns : 假设两种模型的投票程序相同,请考虑使用关注点 :
config/application.rb 配置/ 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 应用程序/控制器/关切/ 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
In case you prefer using meaningful variable names instead of just @object
, you can do this kind of thing: 如果您更喜欢使用有意义的变量名而不是
@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
Then in your controllers you should include that concern: 然后,在您的控制器中,您应该包括以下问题:
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
You should also be sure to set appropriate routes in your config/routes.rb file, so that upvote
and downvote
actions exist in both of the controllers. 您还应该确保在config / routes.rb文件中设置适当的路由,以便两个控制器中都存在
upvote
和downvote
操作。 As you could already understand, you should pass upvote_universe_path
or upvote_characters_path
to your partial to make this work (same for the downvoting). 如您已经了解的那样,您应该将
upvote_universe_path
或upvote_characters_path
传递给您的部分服务器,以使此工作有效(与下一次upvote_universe_path
相同)。 Each route should pass id
of the object to controller's action. 每个路由都应将对象的
id
传递给控制器的操作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.