The Best practices for Rails App Development

The Best practices for Rails App Development

Rails_development_new_0912

Introduction:

“Rails” is an amazing framework to develop web applications quickly through its inbuilt helper libraries. However, there are certain best practices that you should follow to get your rails app perform better.

Conventional programming methods:

Most developers love to place the logic inside the controller and use the model for the “Active Record” operation only. This leads to a “Fat controller and skinny model” interface which eventually kills an app’s performance and looses the maintainability of the code. This way, application stops responding when the load is high.

What should be the best practices?

Below, I have mentioned some of the most essential and useful practices that should be followed by every Ruby on Rails developer.

Fat Model, Skinny Controller

Write all the non-response-related logics inside the model with nice and testable methods; and don’t forget to use comments. You should follow the Ruby on Rails motto i.e. “Fat Model, Skinny Controller”. Because the “skinny” controller offers a nice interface between the view and model.

By moving any logic that isn’t about the response (for example, setting a flash message, or choosing whether to redirect or render a view) to the model instead of the controller, not only you can reuse the codes where

possible but you’ve also made it possible to test your code.

Reusable Scopes

A scope is a set of constraints on database interactions (such as a condition, limit, or offset) that are chainable and reusable.

Let’s see a simple example:

[sourcecode language=”plain”]
def index
@paid_users= User.where(“is_active=? AND is_paid=?”,true, true).order(“name”)
@unpaid_users= User.where(“is_active=? AND is_paid=?”, true, false).order(“name”)
[/sourcecode]

You can change it to this:

[sourcecode language=”plain”]
def index
@paid_users= User.paid.all
@unpaid_users= User.unpaid.all
end[/sourcecode]

Then, you can move the logic to your User model, where it might look like this:

[sourcecode language=”plain”]
scope :paid, lambda { where(“is_active=? AND is_paid=?”,true, true).order(“name”) }
scope :unpaid, lambda { where(“is_active=? AND is_paid=?”,true, false).order(“name”) }
[/sourcecode]

Using the methods User.paid.all and User.unpaid.all, we’ve not only made it simpler to test our code, but also made it possible to reuse that same set of conditions in another location.

You should avoid the use of default_scope because:

  1. You can’t override default scope
  2. default_scope will affect your model initialization

Package Your Code into Gems and Plugins

Writing a particular set code more than once for different applications is exhausting as well as redundant, hence, it is advisable to create a plugin or gem to use it further. It will save your development time and effort.

Manage Your Attribute Access

While creating or updating an object, Rails usually assigns every attribute without checking the data. Validation only prevents the bad data but doesn’t exactly prevent it from overwriting an attribute that we don’t want to change.

To solve this issue, ActiveRecord is implemented which uses two methods: attr_protected and attr_accessibile.

Using attr_protected, you can declare a blacklist of variables you don’t want to be assigned and using attr_accessible, you can declare a list of variables that can be assigned.

By implementing above steps, you could prevent any mass assignment that could occur via your application’s forms; because if the form does not have the field for a given attribute, doesn’t mean a hacker can’t add it to the request.

From a security perspective, using attr_accessible and attr_protected forces you to think about what should be editable and how to protect the ways in which your class’s attributes are set.

Use Non-database-backed Models

In Rails, Model is not restricted to associate with table. To organize application logic, write it down by creating a new model.

Virtual Attributes

If you are manipulating data before passing it to a model, use virtual attributes instead.

Virtual attributes are a simple own getter and setter methods.

For example
To set a user’s name:

[sourcecode language=”plain”]
@user = User.new(params[:user])
@user.first_name, @user.last_name = params[:user][:name].split(" ", 2)
[/sourcecode]

By using virtual method inside the model

[sourcecode language=”plain”]
def name=(value)
self.first_name, self.last_name = value.to_s.split(“ ”, 2)
end[/sourcecode]

Whenever you set the name attribute, your model will automatically set the first_name and last_name attributes for you, even though name doesn’t exist in the database.

Use Translations

Rails i18n framework makes it easy to declare the map of an abstract context to a string. All you need to do is maintain a YAML file of translations, and use I18n.t / t in your code where there is data shown to the use.

I18n is useful to avail your app to more locales.

Using of after_commit callback

Use “after_commit” instead of using after_create/after_update/after_destroy callbacks to start background processes. Because, in relational database, several operations are wrapped in one unit and pass or fail of transaction depends upon all the operations.

If you use after_create/after_update/after_destroy in first model and if any error occurs in the second model then the background process will raise NotFoundError.

Use select in ActiveRecord association

Use select with has_many and belongs_to on Active Record Associations to speed up the query.

For example:

[sourcecode language=”plain”]
class Patient < ActiveRecord::Base
belongs_to :physician, :select => ‘id,name, surname’
end

class Physician < ActiveRecord::Base
has_many :patients, :select => ‘id,name, physician_id’
end
[/sourcecode]

Fix N+1 Queries

N+1 Queries is a serious database performance problem. Use “Bullet” gem to avoid N+1 query problem

Conclusion:

Employing the above mentioned Rails best practices would keep the code cleaner and reusable. The application performance would increases tremendously and the maintenance of the code will be easier.

Tags:
,
Jay
Jayadev Das
jayadev.das@andolasoft.com

Do what you do best in – that’s what I’ve always believed in and that’s what I preach. Over the past 25+ years (yup that’s my expertise ‘n’ experience in the Information Technology domain), I’ve been consulting to small, medium and large companies ‘bout Web Technologies, Mobile Future as well as on the good-and-bad of tech. Blogger, International Business Advisor, Web Technology Expert, Sales Guru, Startup Mentor, Insurance Sales Portal Expert & a Tennis Player. And top of all – a complete family man!