IcyTruck is a web application that is built with Ruby on Rails. It allows user to sign up either as an ice cream truck owner or as a customer. Trucks can create their ice creams, even their unique flavors and customers can place ice cream orders. Nested resources, nested forms, omniauth-facebook, custom validations are used. However, this post will be about callbacks, helper methods and custom Active Record queries which are also used in IcyTruck.

Custom Active Record Queries

Model objects that inherit from ActiveRecord::Base and contain Active Record Associations macros have methods that perform database queries. This makes object oriented programming so much easier and quicker. However these methods triggers multiple queries in order to retrieve the data we are trying to access. For example:

Based on this database tables diagram, we can run: Truck.find_by(id:1).icecreams code to access the menu of the icecream truck that first customer ordered from. This will perform:

AR queries. However if we want our code to execute more efficiently we can create a custom query that can retrieve same data with performing only one query. In this example above our custom query that gives same result would be Icecream.where("truck_id = ?", 1) and this query would perform:

As you can see, our custom query performs only one query. The time difference between first and second query methods depends on how many ice creams and trucks our database has. The more data our code looks into, the more time it takes.

What if we want to use a custom query in multiple places throughout our code ? We don’t want to be repetitive. In order to do that, we declare a class method in our model that we want to perform our query on.

For example, in IcyTruck, the trucks in the same zip code area show up for truck owners and customers. We need a custom query method so we can use every time our server gets a request for truck index page. Our custom query method would look like :

The argument that is passed will be the zip code we want filter our trucks through. This method returns an array of truck objects that we display in index view page.

To make our custom query method neat and easy to spot, we can use #scope method. Scope method is preferred rather than class method because makes our code cleaner, easier to read so we can spot them easily. For the example above, our scope method would be like:

:in_the_area_of is our class method name, ->(zipcode) is our argument and { where("zipcode = ?, zipcode) } would be our method block.

Helper Methods

There are different types of helper methods. They can be used for model objects, views and controllers to clean up our code. Sometimes a helper method can be called in controllers and views too. For the sake of keeping our code eloquent and clean, we should keep helper methods in the right places.

Controller Helper Methods

These methods live in our controllers, including ApplicationController. We should keep them in the controller that we use them. Strong params methods are good example of a controller helper method.

However, sometimes some helper methods are needed in controller and views. Therefore, we place them in ApplicationController and in order to use them in our views as well, they should be passed as an argument of #helper_method macro method.

View Helper Methods

View helper methods are the ones we use in only our erb files. They are placed in module ApplicationHelperin app/helpers/application_helper.rb file. They help us to carry our application’s logic apart from view files which makes our code easy for debugging, reading, overriding.

Model Helper Methods

Model helper methods can be used for building our application logic, custom validations, lifecycle callbacks etc. They are related to the model only.

Active Record Callbacks

While the user interacts with our app, application’s objects can be manipulated such as created, deleted, updated. Active Record Callbacks are macro methods that allows us carry our application logic during objects lifecycle.

In the photo above, we use after_destroy macro that is executed right after an ice cream is deleted from database and triggers #cancel_orders_upon_delete which deletes all orders that include that ice cream.

Software Developer

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store