This document is meant to server as a jumping off point and reference guide for anyone that is new to programming in Rails. This document will have some very basic concepts and may be useful for anyone needing a quick jog of the memory when developing apps on Rails. This document is not a complete review of Rails and everything the framework offers.
## ActiveRecord ActiveRecord is a relational database ORM Pattern (Object Relational Mapper). In short Active record maps: * Classes to tables. * Objects to rows of data within that table. * Getters and setters to columns in that table.NOTE: If you are using this document you should have a basic understanding of how to use terminal/commandline, irb and how to install Ruby Gems and Rails.
Put another way, ActiveRecord abstracts/translates object oriented code written in Ruby to SQL. ActiveRecord says an object correlates directly with a row of data in a table. Each row of data correlates to an object, each column has getters and setters it can set automatically.
### ActiveRecord Pattern #### Database In our database we have a user table as follows:id | username | |
---|---|---|
1 | bob | bob@example.com |
2 | fred | fred@example.com |
3 | kim | kim@example.com |
In our Rails directory we would put a User model in the following:
app/models/user.rb
The user.rb file would then contain a user class.
class User < ActiveRecord::Base
...
end
By default, the model will look to the table with the lowercase plural name of the model. So a "User" model would look for a "users" table.
When we instantiate a user object, we automatically have getters and setters for all columns.
IMPORTANT: An ActiveRecord object wraps a row of data in the database table.
Create in-memory User objects:
user = User.new(username:'joe', email:'joe@example.com')
Save it to the database:
user.save
user = User.create(username: 'chris')
Retrieve column values:
user = User.find_by username: 'joe'
user.email
id | username | |
---|---|---|
1 | bob | bob@example.com |
2 | fred | fred@example.com |
3 | kim | kim@example.com |
comments table
id | body | user_id |
---|---|---|
1 | hi there | 2 |
2 | this is fun | 3 |
3 | foo | 2 |
The id on both tables above is the primary key. The user_id on the comments table is a foreign key, which provides the relationship back to the users table.
We would then have the following models with the relations.
app/models/user.rb
class User
has_many :comments
end
app/models/common.rb
class Comment
belongs_to :user
end
user = User.create(username:'bob')
Create associations from relations:
comment = user.comments.create(body:'hi')
user.comments << comment
comment.user = user; comment.save
Or manually create the association:
comment = Comment.create(user: user, body: 'hi')
comment = Comment.create(user_id: user.id, body: 'hi')
Then, traverse associations:
comment.user.username
(returns string)user.comments
(returns array-like object)user.comments.where(body: 'hi')
user.comments.each do |comment|
puts comment.body
end
users table
id | username | |
---|---|---|
1 | bob | bob@example.com |
2 | fred | fred@example.com |
3 | kim | kim@example.com |
memberships table (the join table)
id | user_id | group_id |
---|---|---|
1 | 2 | 2 |
2 | 1 | 2 |
3 | 3 | 1 |
groups
id | name |
---|---|
1 | ruby folk |
2 | python peeps |
In the previous 3 tables the id on each table is the primary key. The membership table is the join table and keeps track of the relationship of users to groups and groups to users.
At the model layer, we want to use has_many :through, which is basically two 1:M associations. We must set up the association in the models as follows:
app/models/user.rb
class User
has_many :memberships
has_many :groups, through: :memberships
end
app/models/membership.rb
class Membership
belongs_to :user
belongs_to :group
end
app/models/group.rb
class Group
has_many :memberships
has_many :users, through: :memberships
end
user = User.create(username: 'bob')
group = Group.create(name: 'ruby folk')
Create association from relations:
user.groups << group
group.users << user
Or manually create the association:
membership = Membership.create(user: user, group: group)
Membership.create(user_id: user.id, group_id: group.id)
Then, traverse associations:
user.groups.first.name
group.users do |user|
puts user.username
end
More coming soon...