Ruby on rails 我将如何重构我的控制器';什么是自定义方法?
我正在构建一个类似StackOverflow的克隆,以供研究之用。用户可以为某人的问题投票,从而提高或降低分数。我的方法工作得很好,但是重复和控制器逻辑的数量困扰着我Ruby on rails 我将如何重构我的控制器';什么是自定义方法?,ruby-on-rails,ruby-on-rails-4,Ruby On Rails,Ruby On Rails 4,我正在构建一个类似StackOverflow的克隆,以供研究之用。用户可以为某人的问题投票,从而提高或降低分数。我的方法工作得很好,但是重复和控制器逻辑的数量困扰着我 用户拥有多张选票 这个问题有很多票 投票属于问题/用户 路线: concern :voteable do post 'votes/voteup', to: 'votings#voteup', as: :voteup post 'votes/votedown', to: 'votings#votedown', a
- 用户拥有多张选票
- 这个问题有很多票
- 投票属于问题/用户
concern :voteable do
post 'votes/voteup', to: 'votings#voteup', as: :voteup
post 'votes/votedown', to: 'votings#votedown', as: :votedown
end
resources :questions, concerns: [:commentable, :favoriteable, :voteable] do
...
end
投票控制员
class VotingsController < ApplicationController
def voteup
@question = Question.find(params[:question_id])
unless @question.user == current_user # checks if the user is the author
if current_user.voted?(@question.id) #checks if user already voted
@vote = current_user.votes.find_by(question_id: @question)
@vote.update_attributes(score: 1)
else
@vote = Vote.create(user: current_user, question: @question, score: 1)
end
end
redirect_to :back
end
def votedown
@question = Question.find(params[:question_id])
unless @question.user == current_user
if current_user.voted?(@question.id)
@vote = current_user.votes.find_by(question_id: @question)
@vote.update_attributes(score: -1)
else
@vote = Vote.create(user: current_user, question: @question, score: -1)
end
end
redirect_to :back
end
end
我想消除这两种方法中的重复,但如何做到?
我是否应该创建一个类似投票的方法和一个使用指定参数(向上/向下)指向它的路线,然后根据if/else分配分数?听起来很肮脏,但这是我唯一想到的。我相信一定有一个漂亮的Rails解决方案 用户类可以持有一个名为
vote\u for(问题、分数)
的方法,其定义如下:
# class User
def vote_for(question, score)
vote = self.votes.where(question_id: question.id).first || Vote.new(user: self, question: question)
vote.score = score
vote.save
end
class VotingsController < ApplicationController
before_filter :set_question, only: %w(voteup votedown)
def voteup
current_user.vote_for(@question, 1)
end
def votedown
current_user.vote_for(@question, -1)
end
protected
def set_question
@question = Question.find(params[:id])
end
这将返回
TRUE
或FALSE
,而不是从数据库检索到的完整对象,然后转换为Ruby对象。谢谢。我走了你的路,经过一些重构,我的代码现在看起来好多了
# class User
def vote_for(question, score)
vote = self.votes.where(question_id: question.id).first || Vote.new(user: self, question: question)
vote.score = score
vote.save
end
class VotingsController < ApplicationController
before_filter :set_question, only: %w(voteup votedown)
def voteup
current_user.vote_for(@question, 1)
end
def votedown
current_user.vote_for(@question, -1)
end
protected
def set_question
@question = Question.find(params[:id])
end
def voted?(question)
self.votes.exists?(question_id: question)
end