3

I read the documentation on Rails Validation, but didn't see much about how to work with errors in the controller.

Question -- Are render :new and render :edit when .save fails the proper way to show the errors after submitting the form?

Also, is there a way that I can keep the polls/new and polls/edit routes the same as when the form was initially loaded?

In my view I have the @poll.errors.any? ... @poll.errors.full_messages.each do ... block. These errors are successfully called if I have the following code in my controller, with render :new being the main point of interest:

class PollsController < ApplicationController    
  def create
    @poll = Poll.create(poll_params)

    if @poll.save
      redirect_to polls_path
    else
      render :new
    end
  end

The form shows up, but my route changes from polls/new back to polls and none of my options are built. I also tried redirect_to new_poll_path but of course that starts from scratch and shows no errors.

enter image description here

1 Answer 1

11

Take the following scenario: A user navigates to the form in your new action, enters some data, and presses "submit". By default (i.e. assuming you're using restful routes), rails will submit your form to the create action in your controller. Assume that the user entered some data that was incorrect and would cause @poll.save to fail. In your case, this code would run:

render :new

In this case, you have told rails to simply render the new partial again. However, since you've told rails to render the new partial from your create action, you will see /polls in your url bar since /resource_name is how rails implements the create portion of its restful routing system (and you've defined your resource to be called "polls".

To answer this question:

Are render :new and render :edit when .save fails the proper way to show the errors after submitting the form?

The short answer is yes. In rails, this is typically the preferred way of showing errors to users who enter incorrect data into a form. However, if you wanted to ensure that /edit or /new was in the url bar after an unsuccessful form submission, you would need to replace:

render :new

with

redirect_to new_poll_path, alert: @poll.errors.full_messages

This solution will cause the errors in your @poll object to be displayed in your flash messages area (assuming you have that set up). However, I don't personally like this solution much because flash messages typically aren't intended to be used this way. This begs the question:

Why can't I use @poll.errors.full_messages after a redirect?

The reason for this is because your @poll object (in the create action) is carrying the error messages. As soon as @poll.save fails, your @poll object will be carrying the error messages that caused the .save method to fail. If you were to redirect away from the create action back to the new or edit actions, the @poll object with the errors would be replaced by a new @poll object as defined in either the new or edit actions in your controller. Therefore, using render allows you to give the @poll object with the error messages back to the appropriate action so that the error messages can be displayed.

Sign up to request clarification or add additional context in comments.

1 Comment

wow, thank you very much. i shared this with the rails chart and people were excited to learn that alert can be used in combination with redirect_to

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.