Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
507 views
in Technique[技术] by (71.8m points)

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

I have a resource called Books. It's listed as a resource properly in my routes file.

I have a new action, which gives the new view the standard:

@book = Book.new

On the model, there are some attributes which are validated by presence, so if a save action fails, errors will be generated.

In my controller:

@book = Book.create
...  # some logic
if @book.save
  redirect_to(@book)
else
  render :new
end

This is pretty standard; and the rationale for using render:new is so that the object is passed back to the view and errors can be reported, form entries re-filled, etc.

This works, except every time I'm sent back to the form (via render :new), my errors show up, but my URL is the INDEX URL, which is

/books

Rather than

/books/new

Which is where I started out in the first place. I have seen several others posts about this problem, but no answers. At a minimum, one would assume it would land you at /books/create, which I also have a view file for (identical to new in this case).

I can do this:

# if the book isn't saved then
flash[:error] = "Errors!"
redirect_to new_book_path

But then the @book data is lost, along with the error messages, which is the entire point of having the form and the actions, etc.

Why is render :new landing me at /books, my index action, when normally that URL calls the INDEX method, which lists all the books?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...