Reputation: 11
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.
Upvotes: 0
Views: 75
Reputation: 239240
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 %>
Upvotes: 0