Rails Routing default behavior and Invalid New Records

I have a question about the design decision behind the rails default routing.

The normal routing is, to create a new record we GET /things/new. However, when the user submits a new thing he is posting to #create at /things. The vanilla create action looks like:

def create

@thing = Thing.new(params[:thing])

if @thing.save

redirect_to(@thing), :notice => “Thing created!”

else

render ‘new’

end

end

Hence, if validation fails, the user is presented with the form view he just saw at /things/new, but now the URL he sees is /things.

Now, this really bothers me for two main reasons:

  1. Showing the invalid record at /things is making a GET request on things, but GET /things belongs #index.

  2. Because the URL does not match the view the user is seeing, if the user hits reload he loses his form and gets the index.

What I’d like to know is, what is the rational behind this routing setup? Why shouldn’t the #create action be routed to receive POST requests at /things/new instead of /things.

I know that tons of time, energy, and careful decision-making has gone into making rails - and I love the framework - but I would feel a lot better if I understood the logic behind this decision. From an end-user-experience point-of-view this seems quite confusing to me.

Thanks!

I have a question about the design decision behind the rails default
routing.

The normal routing is, to create a new record we GET `/things/new`. However,
when the user submits a new thing he is posting to #create at `/things`. The
vanilla create action looks like:

def create
@thing = Thing.new(params[:thing])
if @thing.save
redirect_to(@thing), :notice => "Thing created!"
else
render 'new'
end
end

Hence, if validation fails, the user is presented with the form view he just
saw at `/things/new`, but now the URL he sees is `/things`.

Now, this really bothers me for two main reasons:
1. Showing the invalid record at `/things` is making a GET request on
things, but GET `/things` belongs #index.

It is not making a new GET request.

2. Because the URL does not match the view the user is seeing, if the user
hits reload he loses his form and gets the index.

Nope. Hiting refresh will show a warning from browser that you are
making same POST request again. If you confirm then again the form
with validation errors is presented (assuming that nothing changed and
the validation worked same way this time)

What I'd like to know is, what is the rational behind this routing setup?
Why shouldn't the #create action be routed to receive POST requests at
`/things/new` instead of `/things`.

Because you are modifying the collection which is available under /
things . /things/new is just view that is necessary only for browsers
to display the form with form fields to submit. Other application
clients using API (XML, JSON) do not need it. They send GET requests
to /things to obtain a list of items and POST requests to /things to
create a new record.

Current implementation allows you to :
a) display errors messages thanks to using the record that contains
them when rendering the view.
b) submit the form again with refresh when it failed.
c) on success you are redirected to the list. Hitting refresh there
will refresh the list instead of resubmitting the form.

Robert Pankowecki