Rails new vs create

Why is there a need to define a new method in RESTful controller, follow it up with a create method?

Google search didn't provide me the answer I was looking for. I understand the difference, but need to know why they are used the way they are.


Solution 1:

Within Rails' implementation of REST new and create are treated differently.

An HTTP GET to /resources/new is intended to render a form suitable for creating a new resource, which it does by calling the new action within the controller, which creates a new unsaved record and renders the form.

An HTTP POST to /resources takes the record created as part of the new action and passes it to the create action within the controller, which then attempts to save it to the database.

Solution 2:

With regard to Rails Models the ActiveRecord::Base documentation states:

create(attributes = nil) {|object| ...}

Creates an object (or multiple objects) and saves it to the database, if validations pass. The resulting object is returned whether the object was saved successfully to the database or not.

new(attributes = nil) {|self if block_given?| ...}

New objects can be instantiated as either empty (pass no construction parameter) or pre-set with attributes but not yet saved (pass a hash with key names matching the associated table column names). In both instances, valid attribute keys are determined by the column names of the associated table — hence you can‘t have attributes that aren‘t part of the table columns.

So create instantiates the new object, validates it, and then saves it to the database. And new only creates the local object but does not attempt to validate or save it to the DB.

Solution 3:

New instantiates a new Model instance, but it is not saved until the save method is called.

Create does the same as new, but also saves it to the database.

Sometimes you want to do stuff before saving something to the database, sometimes you just want to create and save it straight away.

Solution 4:

The RESTful parts of Rails are made to be very close to how the HTTP protocol works. In the HTTP protocol, a GET request isn't supposed to modify any data. Logically, if you look at the way all of the RESTful actions in Rails work, they will match up with HTTP actions. A POST is for generating new data, so it is logically create. You use a GET to serve the form version of that or in other words, the new action. Index and show are also GETs, update is a PUT (or PATCH in Rails 4+), and destroy is a DELETE in HTTP.

In addition, it nicely separates the logic in the controller and gives you a smooth way to deal with errors (by re-rendering the new action with error messages).