If you’re coming from PHP, there can seem to be a whole load of key concepts that need clarification before you can even get started.
And the very first one you have to deal with is routes.
In PHP, if you want some interaction between your pages you just add links between them – regular A tags with HREF attributes.
But in Rails, that’s not enough, you need to create routes.
So let’s dive in to what they are and why that is.
PHP (and I’m talking about standard PHP, not frameworks like Laravel, of which I have little experience) actually does have its own router. You’ve been using it all along. It’s the filesystem.
If you create a PHP page, documents.php, and put it in the folder /some – then it becomes available at /some/documents.php. When the request is received by your web-server, it parses the incoming request (via your configuration files), then locates the some folder and invokes the documents.php file.
Rails, conceptually, does exactly the same thing – but instead of hosting everything on the file system, it runs its own web-server that invokes pieces of running code, not files from the file-system.
Every Rails application has a file called config/routes.rb – this is the definition of how your application’s router works.
At its simplest, you could put a line that looks like this:
match 'some/documents', to: 'documents#index'
This tells Rails that if it receives a request for ‘some/documents’ it should send it to the “documents” controller and invoke the “index” action. Actually, it creates a new DocumentsController instance and calls “index” (so every request gets a brand-new, fresh controller object).
That’s all well and good – and it gives you the advantage that your entire Rails app can be held as a single running process, rather than being loaded from file on every request.
But the real advantage of Rails is that it saves you time. And a huge chunk of those time savings come because Rails expects you to follow certain conventions (and therefore can shortcut lots of code and configuration because it already knows where things are going to work).
In particular, Rails has a convention called Restful Routing. This defines a way of planning your routes that broadly follow that used by a REST API. So for any “resource” in your application (documents, people, orders, whatever), you will probably want to be able to list the items available, view an individual item, fill in a form to create a new one, actually create a new one, fill in a form to edit an existing one and update the existing item. And finally delete the item.
If you go back to your routes file and replace the “match” line we had above with this:
then Rails generates a whole load of routes for you, following the Restful convention. Those routes are:
- GET documents/index – list all documents
- GET documents/123 – show document 123
- GET documents/new – show the form for creating a new document
- POST documents – create a new document
- GET documents/123/edit – show the form for editing an existing document
- PATCH documents/123 – update an existing document
- DELETE documents/123 – delete an existing document
Note how they use HTTP verbs to distinguish between different actions.
For this to work, your DocumentsController needs to have methods equivalent to each of the actions. These are:
- index – list all documents
- show – show document 123
- new – show the form for creating a new document
- create – create a new document
- edit – show the form for editing an existing document
- update – update an existing document
- destroy – delete an existing document
At first, it does look like a load of overhead, compared to PHP, but it provides a clear separation of concerns – the router sends requests to the right place and each controller has a well-defined, limited, role.