Model associations are an extremely important part of a rails app that identify how models interact with each other and the relationships between them. If you’ve ever worked with ORM providers, or even basic OO principles, then you’ll be able to pick this up very quickly.
This follows on from a previous post Beginner Rails – Creating a new application where we’re looking at a simple implementation of a photo blog.
When you create a model in rails, it generally comes stock with nothing added except for the base definition of its properties and inherited methods. Models are located in the appmodels folder of your project, and inherit ActiveRecord::Base to provide it with the database-aware behaviors.
To illustrate how this works, we’ll implement the remaining two models from the previous post:
- Photo
- Comment
To create a model, you use the command:
rails g model ModelName propertyName1:type1 propertyName2:type2
So for the Photo model:
rails g model Photo gallery_id:integer title:string
You’ll notice that because photo belongs to a gallery, the gallery_id for that photo is created that’ll be used as a foreign key.
This creates the relevant model, tests and migration script. Use
rake db:migrate
to run the migration and create the photos table in the database
Now that the model has been created, we’ll create our first association. This association will be that a Photo belongs to a Gallery, and a Gallery can have many Photos.
To specify that a Photo belongs to a gallery, we make the change in appmodelsphoto.rb:
And now to specify a Gallery has many photos, open up appmodelsgallery.rb:
By adding two simple lines of code, ActiveRecord is now aware of the relationships between these entities and can work with objects far easier.
Let’s go into the console and try it out:
Here we created a new gallery which creates it in memory, and then running the save() method which commits it to the database.
If you want to do the new and save procedure in one step, you can call the “create” method instead which we’ll now use to add some photos to this gallery:
So now our database has 1 gallery that has 2 photos in it. We can leverage the associations we created before to navigate these objects:
The next phase is to add the ability to create comments against these photos. The association is similar to the Gallery/Photo relationship with one addition: A comment belongs to a single photo, a photo can have many comments, and a gallery has many comments through its photos.
Let’s start by creating the Comment model:
rails g model Comment photo_id:integer body:text
rake db:migrate
Then modifying the Comment & Photo models:
And then create a new association in the Gallery model that will retrieve all of the comments for all of the photos related to it:
Once that’s done, reload the changes in your irb console by using:
reload!
And then add some comments to each photo:
Now we can try out all of our associations, including the “by relation” ones from Gallery to Comment:
In this example, we looked at belongs_to and has_many associations, but the full list of associations Rails supports is:
- has_one
- has_many
- belongs_to
- has_and_belongs_to_many
Which is enough to define any type of association you have.
This is a very simple example, but these principles can be applied at a much larger scale to sufficiently manage all of your objects. The next post will define the validations that define the data rules for each object.