In Rails when a resource create action fails and calls render :new, why must the URL change to the resource's index url? In Rails when a resource create action fails and calls render :new, why must the URL change to the resource's index url? ruby-on-rails ruby-on-rails

In Rails when a resource create action fails and calls render :new, why must the URL change to the resource's index url?


It actually is sending you to the create path. It's in the create action, the path for which is /books, using HTTP method POST. This looks the same as the index path /books, but the index path is using HTTP method GET. The rails routing code takes the method into account when determining which action to call. After validation fails, you're still in the create action, but you're rendering the new view. It's a bit confusing, but a line like render :new doesn't actually invoke the new action at all; it's still running the create action and it tells Rails to render the new view.


I just started with the Rails-Tutorial and had the same problem.The solution is just simple: If you want the same URL after submitting a form (with errors), just combine the new and create action in one action.

Here is the part of my code, which makes this possible (hope it helps someone^^)

routes.rb (Adding the post-route for new-action):

...    resources :books    post "books/new"...

Controller:

...def create    @book = Book.new(book_params)    if @book.save        # save was successful        print "Book saved!"        else        # If we have errors render the form again           render 'new'    endenddef new     if book_params        # If data submitted already by the form we call the create method        create        return    end    @book = Book.new    render 'new' # call it explicitendprivatedef book_params    if params[:book].nil?  || params[:book].empty?        return false    else        return params.require(:book).permit(:title, :isbn, :price)    endend

new.html.erb:

<%= form_for @book, :url => {:action => :new} do |f| %>  <%= f.label :title %>  <%= f.text_field :title %>  <%= f.label :isbn %>  <%= f.text_field :isbn %>  <%= f.label :price %>  <%= f.password_field :price %>  <%= f.submit "Save book" %><% end %>


Just had the very same question, so maybe this might help somebody someday. You basically have to make 3 adjustments in order for this thing to work, although my solution is still not ideal.

1) In the create action:

if @book.save  redirect_to(@book)else  flash[:book] = @book  redirect_to new_book_pathend

2) In the new action:

@book = flash[:book] ? Book.new(flash[:book]): Book.new

3) Wherever you parse the flash hash, be sure to filter out flash[:book].

--> correct URL is displayed, Form data is preserved. Still, I somehow don't like putting the user object into the flash hash, I don't think that's it's purpose. Does anyboy know a better place to put it in?