Naming conventions in RoR development

By default, Active Record uses some naming convention to know how the relationship between models and database tables should be created. Rails pluralizes class names to find the appropriate database table. For example, for the Book class, create a database table named books. Rails’ pluralization mechanisms are very powerful, being able to pluralize (and singular) both correct and incorrect words. When using class names made up of two or more words, the model class name must follow Ruby conventions using the CamelCase form, while the table name must contain words separated by underscores. Examples:

Database table – Plural form with words separated by underscores (ie, book_clubs).

The model class is a single number with the first capital letter in each word (i.e., BookClub).

Model/Class Table/Scheme

articles

LineItem line_items

Deer deers

mouse mice

Person people

Schema Conventions

Active Record uses naming conventions for columns in database tables, depending on the purpose of those columns.

Foreign Keys – These fields should be named after singularized_table_name_id (ie, item_id, order_id). These are the fields that Active Record looks for when creating relationships between your models.

Primary Keys – By default, Active Record uses a numeric column named id as the table’s primary key. This column will be automatically created when using Active Record migrations to create tables.

There are also some optional column names that add extra features for Active Record instances:

created_at – The current date and time will be automatically set when the entry is first created.

updated_at – The current date and time will be automatically set whenever the entry is updated.

lock_version – Adds an optimistic lock to the model.

type – Indicates that the model uses Single Table Inheritance.

(association_name)_type – Stores the type for polymorphic associations.

(table_name)_count – Used to cache the number of objects owned by a link. For example, the comments_count column in the Article class, which can have multiple associated Comment instances, will cache the number of existing comments for each article.

NOTE: Although these column names are optional, they are actually reserved by Active Record. Avoid reserved keywords unless you want additional functionality. For example, type is a reserved word for defining a table using Single Table Inheritance (STI). If you are not using STI, try using a similar word such as “context”, which can also neatly describe the data you are modeling.

Creating Active Record Models

Creating Active Record models is very easy. All you need to do is subclass ApplicationRecord and you’re done:

class Product < ApplicationRecord

end

This will create a Product model by linking it to the products table in the database. By doing so, you will also be able to associate the columns of each row of this table with the attributes of your model instances. Let’s say the products table was created using the following SQL statement:

CREATE TABLE products (

   id int(11) NOT NULL auto_increment,

   name varchar(255),

   PRIMARY KEY (id)

);

Following the above scheme, it will be possible to write code like this:

p = product.new

p.name = “Some Book”

puts p.name # “Some Book”

Redefining naming conventions

But what if you’re following a different naming convention, or if you’re using a new Rails application with an old database? Not a problem, you can just override the default conventions.

ApplicationRecord inherits from ActiveRecord::Base which defines a number of useful methods. You can use the ActiveRecord::Base.table_name= method to specify the name of the table to be used:

class Product < ApplicationRecord

  self.table_name = “my_products”

end

If you do this, you must manually define the name of the class containing the fixtures (my_products.yml) using the set_fixture_class method in the test definition:

class ProductTest < ActiveSupport::TestCase

  set_fixture_class my_products: Product

  fixtures :my_products

  …

end

It is also possible to override the column that should be used as the table’s primary key using the ActiveRecord::Base.primary_key= method:

class Product < ApplicationRecord

  self.primary_key = “product_id”

end

CRUD: Reading and writing data

CRUD is an abbreviation for four verbs used to describe data operations: Create (create), Read (read), Update (update) and Delete (delete). Active Record automatically creates methods that allow an application to read and act on the data stored in its tables.

Creation

Active Record objects can be created from a hash, a block, or from manually specified attributes after creation. The new method will return a new object, while create will return an object and save it to the database.

For example, given a User model with name and occupation attributes, calling the create method will create and save a new record to the database:

user = User.create(name: “David”, occupation: “Code Artist”)

Using the new method, an object can be initialized without saving:

user = User.new

username = “David”

user.occupation = “Code Artist”

Calling user.save will commit the record to the database.

Finally, if a block is provided, both create and new will pass a new object into that block for initialization:

user = User.new do |u|

  u.name = “David”

  u.occupation = “Code Artist”

end

Reading

Active Record provides a rich API for accessing data in a database. Below are some examples of the various data access methods provided by Active Record.

# will return a collection with all users

users = User.all

# will return the first user

user = User.first

# will return the first user named David

david = User.find_by(name: ‘David’)

# will find all users named David who are Code Artists and sort them by created_at in reverse chronological order

users = User.where(name: ‘David’, occupation: ‘Code Artist’).order(created_at: :desc)

For more information about queries in Active Record models, see the Active Record Query Interface guide.

Update

Once an Active Record object has been received, its attributes can be changed and it can be saved to the database.

user = User.find_by(name: ‘David’)

user.name = ‘Dave’

user.save

A shortcut for this is to use a hash with the attributes associated with the desired values, thus:

user = User.find_by(name: ‘David’)

user.update(name: ‘Dave’)

This is most useful when you need to update multiple attributes at once. If, on the other hand, you need to update multiple records at once, the update_all class method is useful:

User.update_all “max_login_attempts = 3, must_change_password = ‘true'”

Removal

Moreover, once retrieved, the Active Record object can be destroyed, removing it from the database.

user = User.find_by(name: ‘David’)

user.destroy

If you need to delete multiple records at once, you can use the destroy_all method:

# find and remove all users named David

User.where(name: ‘David’).destroy_all

# delete all user

User.destroy_all

Leave a Reply

Your email address will not be published.