Some advanced features in Ruby on Rails

Tram Ho


There are a few features you may not use often, but I think it will be helpful if you know. In this article, I will introduce you to advanced routing (routes), complex layouts and a brief introduction to metaprogramming.

Advanced routing

  • You are probably familiar with the default routes in Rails, when converting RESTful requests using basic HTTP verbs to map them into the corresponding actions in the controller (aka CRUD operation). We can declare resources for the object or specify specific actions using the get / post / put / delete method in the config / routes.rb file. 90% you use to declare basic methods in routing files, but the other 10% give you some other advanced options such as direct navigation rules in routing files, nested routing ( nested routes ) or parse the parameters from incoming requests .

Singular Resource

  • You have encountered this very often in projects. For objects that you want to briefly declare CRUD methods for them, you only need to declare on a line with resources (for example, resouces: posts )
  • Sometimes there are resources that need declaration, which only makes sense for having one. An example is a user dashboard that displays events information based on a specific login user. There is only one dashboard template page, it’s just smart enough to show relevant things to users currently logged in.
  • In this case, it would not make sense to show the index action of the dashboards, as it only needs 1 when changing the logged in user. For any other action that requires the id parameter to distinguish the object (like show , edit ), we don’t need the id parameter anymore.
  • Declaring singular resource :

  • Just note the resource and dashboard declaration form singular. This is also very confusing when many programmers type resources instead of resources when they want to declare the default routing methods (plural).
  • When running the $ rails routes command, the singular resource declaration will only show 6 routes (because we do not use #index) , and there is no id parameter after the routes like:

And it’s different from full resources :

Nested Routes

  • Sometimes it just makes sense for a resource are nested inside one another resource. For example, a list of lessons ( lessons ) is in the list of courses – so you want a URL type ( ). The way to get a path like this is to declare a resource in another resouce declaration block in the routing file:

  • Note that the resources method will include a collection of routes . When you access the URL, you will have to specify the parameter : id for both objects. Specifically it is shown:

  • Also note that the parameter : id is the parameter of the deepest nested resource , the parameter : id of the parent resource is prefixed with the name of that resource ( : course_id ). The view helpers will also automatically create logical paths as if you had course_lesson_path , you need to specify two id parameters for that path as course_lesson_path (1, 3).
  • In fact, sometimes you will only need some nested resource actions – only those actions actually need the parent resource ID to specify it. For example, you can take a specific lesson by only knowing its ID. But to get all the lessons listed under a particular course , you need the course ID so it has to be nested. The same is true when creating lessons , because they will need a parent course of it:

Member – Collection Routes

  • Sometimes you want to add a non-RESTful route in the resource . If you want to add a route for only one member of the resource , use the member method:

  • It will map to the course # preview action in the controller. If you want to add non-RESTful routing for a set in a resource , you don’t need to specify a specific id: id , using the collection method:

  • This upcoming route will map to the courses # upcomming action but you don’t need to declare the parameter : id

Redirect – Wildcard Routes

  • You may want to provide an inconvenient URL for your users but map it directly to another URL you are using. Use redirect :

  • The basic rule here is to only use the redirect method to send one route to another. If your route is simple, it’s a really simple method. But if you also want to send the initial parameters, you need to put the parameter inside % {here} . In the above example, we also renamed the route for convenience by using an alias with the parameter : as . This allows us to use that name in methods like path helper. Run the $ rails routes command to view more details.

Nested layout and input information

  • One problem is the reuse of the views in different pages. We can create unique sections that still reuse many styles so that you can stay consistent throughout the site (eg footer ). We create our own views and then call them using render: template => “your_layout.html.erb”
  • You can also pass information from the first layout to the layout that contains it using the content_for method. This allows you to create logic, custom content in the main layout depending on the content transmitted through your individual layout files. For example, you might have a specific layout file for your static pages, app / views / layouts / static_pages.html.erb . This file will be displayed by default for creating content pages returned from your StaticPagesController (Rails default). However, suppose that you want your static pages to look similar to the rest of the site but you do not want the navigation bar to appear on the top. In this case, you declare content_for in the layout static_pages.html.erb to pass the CSS format to the layout application.html.erb containing it, for example:

  • Then, your application.html.erb layout needs to be set up to capture that content and use that content by adding the yield method:

As a result, layout application.html.erb is equivalent to the following:

  • This is especially useful when you want to make a part of your site look different but not completely redesigned with a completely new layout, you can consider nesting your layouts and passing information from one. Child layout to the parent layout that contains it.

Metaprogramming Rails

  • So what is metaprogramming ? It’s a great and useful concept used on Rails and you can use it yourself. It’s basically the idea that your application or script generates functions or methods or classes quickly while it’s running and can automatically call them.
  • An example of a meta-programmer working in Rails is with route helpers. When your Rails application is activated for the first time, it will download the configuration file / routes.rb , which contains the line “home” => “static_pages # home” so that your users can enter http: //www.yoursite .com / home to go back to the homepage. Rails automatically creates a pair of methods home_path and home_url . That is an example of metaprogramming .
  • What about more flexible situations where you don’t know in advance which method will be called? Ruby provides the send method for this. If you want to run a method on an object, use send on the object with any arguments you want. A simple example you can do on your command line is 1 + 2:

  • In a normal situation, there’s no reason to use send but if you don’t know which method you’ll need to call, that’s a cure-all. Just pass it the name of the method you want to run on the object and Ruby will look for it.
  • But how do you define a new method? In this case, you can use the define_method method , name the method and define the code block inside it. For example:

  • Another very powerful method is method_missing . You have certainly seen errors Hey you, you tried to call a method that doesn’t exist! . Basically, method_missing is a method of BasicObject in Ruby that is inherited by every object and it is called whenever you try to run a method that doesn’t really exist. It also takes in all the arguments you tried to send and any code blocks that come with it. That means you can override method_missing for a certain object and use whatever was called earlier, such as printing a message telling the name of the method you tried to call and the Its argument:

  • Metaprogramming is a convenient feature and has many interesting uses for it. You don’t need to master it to learn Rails, and you should only go into it once you feel comfortable with Rails, but it will certainly be helpful for you to optimize your code and solve some complex issues. Other journals in projects.


Share the news now

Source : Viblo