I'm having trouble getting my redirect and error messages to work. From what I've read you cant get a forms errors to show up when you use redirect so I am trying to use render after it fails.
I have a new post form on a topic page. The url is "topic/1". If you make a post about the topic and something is wrong with the input I want it to go back to the page at topic/1 and display errors and I cant figure out how to get it to go back. Redirect (:back) does what I want but doesnt show the forms errors.
The form on the topic's show.html page:
<%= form_for(@post) do |f| %>
<%= render 'shared/post_error_messages' %>
<%= f.label :title, "Post Title" %>
<%= f.text_field :title %>
<%= f.label :content %>
<%= f.text_field :content %>
<%= f.hidden_field :parent_id, value: 0 %>
<%= f.hidden_field :topic_id, value: @topic.id %>
<%= f.hidden_field :user_id, value: current_user.id %>
<%= f.submit "Create Post" , class: "btn btn-small btn-primary" %>
<% end %>
Create action in the Posts controller
def create
@post = Post.new(post_params)
@topic = Topic.find_by(id: params[:topic_id])
if @post.save
redirect_to @post
else
@topic = Topic.new
render "/topics/show"
end
end
I guess I'm mostly trying to do the render with the id from the page that the form was originally on.
Errors
The problem isn't anything to do with the way you're rendering the form (render
or redirect
) - it's to do with the way you're handling your ActiveRecord
object.
When you use form_for
, Rails will append any errors into the @active_record_object.errors
method. This will allow you to call the following:
form_for error messages in Ruby on Rails
<%= form_for @object do |f| %>
<% @location.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
<% end %>
This only works if you correctly create your ActiveRecord
object, which you seem to do
--
Nested
#config/routes.rb
resources :topics do
resources :posts, path: "", path_names: {new: ""}, except: [:index] #-> domain.com/topics/1
end
You'll be much better using the following setup for a nested
route:
<%= form_for [@topic, @post] do |f| %>
...
<% end %>
This allows you to create a form which will route to the topics_posts_path
, which is basically what you need. The controller will then balance that by using the following:
#app/controllers/topics_controller.rb
Class TopicsController < ApplicationController
def new
@topic = Topic.find params[:topic_id]
@post = Post.new
end
def create
@topic = Topic.find params[:topic_id]
@post = Post.new post_params
end
private
def post_params
params.require(:post).permit(:attributes)
end
end
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments