← Back to Upcase

How to Shrink Controller Action to 5 Lines


(David Silver) #1

How might I refactor this?

  def create
    exam = Exam.find(params[:exam_id])
    @open_exam = current_user.open_exams.build(exam: exam)    
    unless @open_exam.save
      flash[:alert] = @open_exam.errors.full_messages.join(", ")
    end
    redirect_to exam
  end

I could imagine creating a private method to handle the save and flash alert, but it seems like that just obfuscates the code by putting the logic in two different places. I don’t think that would really create any reusable modules.


(Patrik Bóna) #2

You can extract local variable to method:

def create
    @open_exam = current_user.open_exams.build(exam: exam)    
    unless @open_exam.save
      flash[:alert] = @open_exam.errors.full_messages.join(", ")
    end
    redirect_to exam
  end

private

def exam
  @_exam ||= Exam.find(params[:exam_id])
end

You mentioned extracting flash. If you have also update method with same code, then extract it. If not, then it is not needed right now.


(David Silver) #3

Thanks you!