0

I'm having a problem with something that seems like it should use the rails magic on this form. I have an articles controller that has a nested resource comments. I have the comment form on the articles#show page. When I submit the form with invalid data, I want to have access to the error object to flag errors, and I also want to remember what the user entered on the form in the event that the form submission is invalid. Currently I am just redirecting back to the article path (which is what's losing the form data / errors I believe).

The form currently submits and will remember the data if its a valid comment submission. Just no errors / remembering of field values.

routes.rb

Rails.application.routes.draw do
  
  root "articles#index"
  
  resources :articles do
    resources :comments
  end
  
end

articles#show

def show
  @article = Article.find(params[:id])
  @comment = Comment.new
end

comments#create

def create
  @article = Article.find(params[:article_id])
  @comment = @article.comments.build(comment_params)

  if @comment.save
    redirect_to article_path(@article)
  else
    # Thinking this should be a render method
    redirect_to article_path(@article)
  end
end

Comment form:

<%= form_with model: [ @article, @comment ], html: { class: "comment-form" } do |form| %>
  <div class="form-set">
    <%= form.label :commenter %><br>
    <%= form.text_field :commenter, class: "commenter" %>
  </div>

  <div class="form-set">
    <%= form.label :body %><br>
    <%= form.text_area :body %>
  </div>

  <div>
    <%= form.submit class: "btn btn-large btn-success" %>
  </div>
<% end %>

Thank you very much in advance for taking the time to look at this!

Currently I am just redirecting back to the article path (which is what's losing the form data / errors I believe). I'm expecting the form to remember form data that was submitted when the submission is invalid, as well as the ability to show errors.

1 Answer 1

0

The bog-standard, idiomatic Rails solution here is that, on error, you should just re-render the new view instead of redirecting.

Your action should look like this:

def create
  @article = Article.find(params[:article_id])
  @comment = @article.comments.build(comment_params)

  if @comment.save
    redirect_to article_path(@article)
  else
    render 'new' # no: redirect_to article_path(@article)
  end
end

That's really all there is to it. The new view should be written in such a way that it will use values populated within the model to render the form, which you get for free if you're using form_with model: @article. You may need to decorate the form with error messages, and you may choose to show some kind of "top-level" error message above the form, something like:

<% if @article.errors.any? %>
  <p class="error">Your submission contained one or more errors</p>
<% end %>
Sign up to request clarification or add additional context in comments.

Comments

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.