我有一个问题和答案应用程序,类似于stackoverflow的工作方式。投票模型是多态的,属于其他3个模型。使用每个控制器中的投票方法,通过每个模型上的成员POST路由创建投票。
以下user_reputation
方法通过在创建投票时将投票的“第二”值(向上+5,向下为-3)添加到现有用户信誉来工作并设置用户信誉,然而,像这样设置投票的价值感觉是不好的做法。
是否有更清洁/最佳实践方法来实现这一目标?
vote.rb
attr_accessible :value, :votable_id, :votable_type
belongs_to :votable, polymorphic: true
belongs_to :user
validates_inclusion_of :value, in: [1, -1]
validates_presence_of :user_id, :value, :votable_id, :votable_type
validates_uniqueness_of :user_id, scope: :votable_id
validates_uniqueness_of :value, scope: :votable_id
after_create :sum_votes
after_create :user_reputation
def user_reputation
votable = self.votable_type.downcase
user_rep = self.votable.user
if self.value == 1
user_rep.update_attributes(reputation: (user_rep.reputation + 5))
elsif self.value == -1
user_rep.update_attributes(reputation: (user_rep.reputation - 3))
end
end
投票_form.html.erb
<div class="vote">
<div id='<%= "#{votes_count}_#{id}" %>' class="vote-box">
<div class='<%= object.votes_count < 0 ? 'orange-arrows' : 'default-arrows' %>'>
<h1><%= object.votes_count %></h1>
</div>
</div>
<div id="arrows">
<%= link_to raw("▲"), vote_path.call(object, value: 1),id: "upvote", remote: true, method: "post" %><br>
<%= link_to raw(" ▼") , vote_path.call(object, value: -1), id: "downvote", remote: true, method: "post" %>
</div>
</div>
的routes.rb
resources :answers do
member { post :vote }
end
resources :questions do
member { post :vote }
end
resources :comments do
member { post :vote }
end
控制器方法
def vote
@vote = current_user.votes.build(value: params[:value], votable_id: params[:id], votable_type: "Answer")
respond_to do |format|
if @vote.save
format.html { redirect_to :back, notice: "Vote submitted" }
format.js
else
format.html { redirect_to :back, alert: "You can't vote on your own content" }
format.js
end
end
end
答案 0 :(得分:1)
您可以查看Active Record Observer。它实际上与您正在做的相同,但它允许您将这些逻辑与模型分开。
我认为你不需要user_reputation方法中的第一行。