Joe Marion
Joe Marion

Reputation: 406

Refactoring Controller, where to create new methods?

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

Answers (1)

Uzbekjon
Uzbekjon

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

Related Questions