Search code examples
ruby-on-railsrubynested-formsrails-routing

Rails 4 models managed through nested form -- do I need child controllers?


My models are Survey, Question, and Choice, which are nested under SurveysController in views, including by nested forms. In other words, my path is never '/questions/foo', but rather it is always something like: '/surveys', 'surveys/:id', '/surveys/:id/edit' OR nested as '/surveys/:id/questions'.

If this is the case, are my QuestionsController and ChoicesController unnecessary? There aren't any behind the scenes calls/redirects to create/update/delete actions in these child controllers, right?

Just trying to pare down excess code that isn't being used. New to Rails, so thanks for help here.

class SurveysController < ApplicationController
  before_action :set_survey, only: [:show, :edit, :update, :destroy]
  before_action :set_question_formats, only: [:show, :new, :create, :edit, :update]

  def index
    @surveys = current_user.surveys
  end

  def show
    if @survey.questions.any?
      @questions = @survey.questions
    end
  end

  def new
    @survey = QuestionSet.new
    3.times do
      question = @survey.questions.build
      4.times { question.choices.build }
    end
  end

  def edit
  end

  def create
    @survey = current_user.surveys.build(survey_params)
    respond_to do |format|
      if @survey.save
        @survey.remember
        session[:survey_id] = @survey.id
        format.html { redirect_to @survey,
                      notice: "Success!" }
      else
        format.html { render action: 'new' }
      end
    end
  end

  def update
    respond_to do |format|
      if @survey.update(survey_params)
        format.html { redirect_to @survey, notice: 'Survey was successfully updated.' }
      else
        format.html { render action: 'edit' }
      end
    end
  end

  def destroy
    @survey.destroy
    respond_to do |format|
      format.html { redirect_to surveys_url }
    end
  end

  private

    def set_survey
      @survey = Survey.find(params[:id])
      session[:survey_id] = @survey.id
    end

    def survey_params
      params.require(:survey).permit(:id, :title,
        questions_attributes: [:id, :content, :_destroy, :question_format_id, 
        choices_attributes: [:id, :content, :_destroy]])
    end
end

Solution

    • Ok, the QuestionsController is the active controller when questions are nested under surveys as in '/surveys/:id/questions'.
    • Other than this (scoped questions#index) action, the SurveysController is in charge, which takes care of create/update/delete actions for itself and nested associations, questions and choices.
    • Therefore, from my testing thus far, it appears that 1) the ChoicesController is entirely unnecessary, 2) QuestionsController does minimal duty, as in the given context and 3) SurveysController is fully RESTful.