Reputation: 406
I have been working on refactoring out my controller and the question I have keep running into is where should I be creating controller specific methods?
For instance, my create action within a controller would currently look like:
scores_controller.rb
def create
@score = @user.scores.new(score_params)
if @score.save
set_shuffled_questions(@score, params[:score][:selected])
questions = Score.build_quiz(@score, params[:score][:selected])
question = questions.shuffle.first
cookies[:question] = question.question
flash[:success] = "Begin quiz, good luck!"
redirect_to score_quiz_path(@score, question)
else
flash[:alert] = "You suck"
render 'new'
end
end
I am starting to work towards using Sandi Metz' rules for developers, one of them being: Five lines per method. My most natural instinct other than creating an entirely new class filled with methods for this controller would be to put it within the model Score.rb
. If that was the case I would be able to change the method to:
score.rb
# Creates quiz with shuffled questions.
def set_shuffled_questions(selected)
questions = Score.build_quiz(self, selected)
question = questions.shuffle.first
cookies[:question] = question.question
flash[:success] = "Begin quiz, good luck!"
redirect_to score_quiz_path(self, question)
end
scores_controller.rb
def create
@score = @user.scores.new(score_params)
if @score.save
@score.set_shuffled_questions(params[:score][:selected])
else
flash[:alert] = "You suck"
render 'new'
end
end
I am fairly certain this is not the correct way to do it, being that you can not set persistent cookies from the model. What is the appropriate way to refactor controllers with methods?
Upvotes: 1
Views: 177
Reputation: 11813
Firstly, about the "Five lines per method" rule. Don't take it literally. I guess it is just another way of saying "keep your controllers slim (and models flat)". It is better to count "responsibilities", business logic, etc. in your controller methods, rather than lines of code. Plus, you can put several lines of code into one line in Ruby or there can be a boiler plate code, etc. Anyways, don't take it literally.
Back to your question: "Where to put controller code?". If it is a business logic, then put it into your models or separate classes. If you just want to logically separate your code, then I would just create a private methods in my controller and refactor my code. If some parts of the code needs to be shared among several controllers/classes, then I would create a separate utility class.
Upvotes: 1