In the
last article about routs, I haven’t written a lot about anything yet, but
Iskin noticed that I didn’t write anything about RESTful routing. This is a very important part of routing on rails. I did not have a general picture of REST, there were only general ideas taken out of here. So I decided to tackle it more fundamentally.
There is a lot of literature, but it is certainly not translated. And there are a couple of screencasts that I viewed:
Screencast №35 "Custom REST Actions" Ryan BatesScreencast number 93 "RESTful Rails" Bala Paranzh - it is more solid and is a lecture at the university hour. He also has Indian English =).
Excellent translation of articles about REST'/>
REST
REpresentational State Transfer of Resources
For the sake of simplicity, I will formulate as follows: this is such a system of link organization. And links are client-server requests. And requests is first of all HTTP method!
')
REST is more than just reference systems, but practical use on rails is precisely the creation of queries and work with resources.In the old days, it never occurred to me to specify the request method in a link (in the form it is another matter, and that was limited to GET and POST). Now to help us we have (of course, they were before) four HTTP methods: GET, POST, PUT, DELETE. Now the main thing is not the controller methods, but the HTTP methods.
Another news: URLs are no longer for us. Now we use the URI - Uniform Resource Identifier - link to the resource. The RESTful path specifies the URI and HTTP method.
For example, we have a resource - books (books). Each book corresponds to its unique ID. The link to delete, view and update data of some instance (c ID = 1, say) will look like this:
mysite/books/1
But how does the program understand which of the three actions we want to perform? This is where the HTTP method comes in:
GET mysite / books / 1 - show us information about the book with ID = 1
POST mysite / books / 1 - update book info
DELETE mysite / books / 1 - will delete a book
Rail link will look like (delete, let's say) like this:
<%= link_to 'Delete book', book_url(ID), :method => :delete %>
Magic
Such routes are not taken from the air, but are written in the routes.rb configuration file.
# routes.rb
map.resources :books
This short line will create for us seven standard routes:
# HTTP path_var path action
GET books_path / books index
GET book_path (id) / books / id show
GET new_book_path / books / new new
POST books_path / books create
GET edit_book_path (id) / books / id / edit edit
PUT book_path (id) / books / id update
DELETE book_path (id) / books / id destroy
Bala Paranj offers to understand RESTful routes as sentences:
Show me the list of books: GET books_path = GET / books
Show me an edit form for a book with ID = 1: GET edit_book_path (1) = GET / books / 1 / edit
Delete book 1: DELETE book_path (1) = DELETE / books / 1
Update book 1 data: PUT book_path (1) = PUT / books / 1
etc
How to be if we want to create another method. For example, the antique method, which gives us a list of ancient Foleants from our catalog. As a result, we want to get a link like
# HTTP path_var path action
GET antique_books_path / books / antique antique
There are two options for resources:: member and: collection. In this case, our method works (returns) a collection — a list of books (that is, many books, although it may not return any), so we use the: collection option. In addition, since antique _ returns a list to us, we must use the HTTP GET method. If this is difficult to understand, then you can act by analogy: our method essentially does the same thing as the index method - it means that their HTTP methods should be the same.
#routes.rb
map.resources :books, :collection => { :antique => :get }
Now create two more methods:
fire - burn all foleanty
repeblish - republish a book
Then the routes will look like this:
#routes.rb
map.resorces :books, :collection => { :antique => :get, :fire => :delete}, :member => { :republish => :put }
# HTTP path_var path action
GET antique_books_path / books / antique antique
DELETE fire_books_path / books fire
PUT book_path (id) / books / id republish
Why does republish use the PUT method? Because it updates the data (analogue update)
Why does fire_books_path use the DELETE method? Because it deletes (analog of destroy)
Warm up
And now let's look at the following links and think about why they are not RESTful and how to make them RESTful
1. GET /books/edit
2. DELETE /books/1/update
3. DELETE /books/1/destroy
1. If we are editing something, then we are obliged to specify the ID (do not forget that everything is a link to the resource! URI!). Therefore, it would be correct to write
GET / books / 1 / edit
2. To update the data, we use the PUT method, not the DELETE method. To coma, an indication of the HTTP method is sufficient, therefore an indication of the update method is superfluous
PUT / books / 1
3. Again, specifying the controller method is superfluous.
DELETE / books / 1
And now let's discuss what is missing here =)