Ruby on Rails: How would i stay on the same page if the post is not saved?
Solution 1
flash.now
with render
is what you're looking for.
flash.now[:notice] = "Post can not be saved, please enter information."
render :new
Also instead of
flash[:notice] = "Post has been saved successfully."
redirect_to posts_path
you can just write
redirect_to posts_path, :notice => "Post has been saved successfully."
and it will do the same thing. It works only with redirect_to
though, not with render!
Solution 2
Something like this should do what you want:
flash[:notice] = "Post can not be saved, please enter information."
render :new
UPDATE: You updated your question so I have to update my answer. Render is the right way to do this. However, it looks like you load some categories and some other collection of stuff in your new
method. Those same instance variables should be available to your create
method. The cleanest way to do this is put them into another method and have that method used as a before_filter
applied to both create
and new
. Something like this:
before_filter :load_stuff, :only => [:create, :new]
def load_stuff
@arr_select = { 1=>"One",2=>"Two" ,3=>"Three" }
@categories_select = Category.all.collect {|c| [ c.category_name, c.id ] }
end
Then your new
method is pretty much blank and calling render :new
in your create
method should work.
Solution 3
Hey this answer is super late but thought I'd add it for anyone that comes across it. Probably the most simple solution for what you want to achieve is to add required: true to all of the form inputs you want filled out. E.g
f.text_field :title, required: true, class: "whateverclassyouwant"
This way the form will ONLY be submitted if these fields have been filled in correctly and if not an error flash message will pop up on the field that it needs to be completed. The default flash messages that pop up can be custom styled also, Google how to do so.
This way you can remove the else redirect all together in your create method as it will never get to that point, and just have the if save, flash success etc.
shibly
Updated on February 19, 2020Comments
-
shibly about 4 years
def create @addpost = Post.new params[:data] if @addpost.save flash[:notice] = "Post has been saved successfully." redirect_to posts_path else flash[:notice] = "Post can not be saved, please enter information." end end
If the post is not saved then it redirects to http://0.0.0.0:3000/posts , but i need to stay on the page, with text input fields so that user can input data.
post model
class Post < ActiveRecord::Base has_many :comments validates :title, :presence => true validates :content, :presence => true validates :category_id, :presence => true validates :tags, :presence => true end
new method
def new @arr_select = { 1=>"One",2=>"Two" ,3=>"Three" } @categories_select = Category.all.collect {|c| [ c.category_name, c.id ] } end
new.html.erb
<h3>Add post</h3> <%= form_tag :controller=>'posts', :action=>'create' do %> <%= label :q, :Title %> <%= text_field :data, :title, :class => :addtextsize %><br/> <%= label :q, :Content %> <%= text_area :data, :content, :rows=>10 , :class => :addtextarea %><br/> <%= label :q, :Category %> <%= select :data, :category_id, @categories_select %><br/> <%= label :q, :Tags %> <%= text_field :data, :tags, :class => :addtextsize %><br/> <%= label :q, :Submit %> <%= submit_tag "Add Post" %> <% end %>
What should i do ?
-
shibly over 12 yearsNot render, rather i used this, redirect_to new_post_path, and it looks ok. With render i got error. NoMethodError in Posts#create Showing /path/to/app/views/posts/new.html.erb where line #10 raised: You have a nil object when you didn't expect it! You might have expected an instance of Array. The error occurred while evaluating nil.map
-
shibly over 12 yearsNo, i want to stay in the same posts/new page. With render i got error. NoMethodError in Posts#create Showing /path/to/app/views/posts/new.html.erb where line #10 raised: You have a nil object when you didn't expect it! You might have expected an instance of Array. The error occurred while evaluating nil.map, I have updated original post/question, see that again to understand.
-
Taryn East over 12 yearsOk, redirecting is bad because you lose the list of errors that are what the user needs to see to determine what went wrong with their new user. So... instead of redirecting so the bug goes away... lets actually fix the bug. :) can you provide the code at line 10 in new.html.erb
-
U-DON over 12 yearsCan you show your "new"? I think perhaps it is rendering the new.html.erb template, which contains (probably) a post variable or something. You may want to rename addpost to post if that is the case. Still, it's hard to say what the exact problem is without seeing your "new" function.
-
Taryn East over 12 yearsredirect will lose the temporary @post variable which contains all the errors.
-
shibly over 12 yearsI have updated the original post/question. See that again to understand.
-
Jakub Arnold over 12 yearsIt looks like your
new.html.erb
template is using @post variable, which doesn't exist in thecreate
method for the controller. Rename @addpost to just @post and it should work. -
shibly over 12 yearsWhere did you get @post variable? post variable was not used in new.html.erb
-
Jakub Arnold over 12 years@guru Sorry didn't see the edit. You're using
@categories_select
which isn't available in thecreate
method.render
only renders the tempalte, it doesn't execute the controller action, so neither of those two instance methods get set. -
shibly over 12 yearsHow can i make the
@categories_select
available tocreate
method? -
Jakub Arnold over 12 years@guru you're going to have to duplicate the code ... copy it from the
new
method. -
shibly over 12 yearsYes, i copied this line,
@categories_select = Category.all.collect {|c| [ c.category_name, c.id ] }
tocreate
method and no error now withrender :new
, but the result ofrender :new
andredirect_to new_post_path
are similar page with blank input textboxes. -
Carl Zulauf over 12 yearsMy answer is still the correct way. Updated to hopefully make why more clear.
-
Jakub Arnold over 12 years