Learn Rails - Active Record, Associations

Question Click to View Answer

We want to create a User model and a Document model. The User will have many documents and will approve the documents, so we will refer to a user as an "approver". Start by creating a rails app called active_record_fun and change into the directory.

$ rails new active_record_fun
$ cd active_record_fun

Create a User model with name and email attributes.

$ rails generate model User name:string email:string

Create a Document model with title and body attributes. Also add a foreign key that will allow us to refer to the user as "approver".

$ rails generate model Document title:string body:text approver_id:integer

Associate the models.

# models/user.rb
has_many :documents, :foreign_key => "approver_id"

# models/document.rb
belongs_to :approver, :class_name => 'User'

Create seed data, create the database tables, and then seed the database.

# db/seeds.rb
user = User.create :name => "Bob", :email => "bob@example.com"
user.documents.create :title => "Official new", :body => "This is boring"
$ rake db:migrate
$ rake db:seed

Open rails console and demonstrate how to find the user for a given document.

$ rails c
>> Document.first.approver  # normally this would have been Document.first.user, but this would not have been as clear

Add code to enable the following behavior.

$ rails c
>> document = Document.first
>> document.approver_name
=> "Bob"
>> document.approver_email
=> "bob@example.com"
models/document.rb
delegate :name, :email, :to => :approver, :prefix => true

Modify the code to enable the following behavior.

$ rails c
>> document = Document.first
>> document.person_name
=> "Bob"
>> document.person_email
=> "bob@example.com"
# models/document.rb
delegate :name, :email, :to => :approver, :prefix => :person

Modify the code to enable the following behavior.

$ rails c
>> document = Document.first
>> document.name
=> "Bob"
>> document.email
=> "bob@example.com"
# models/document.rb
delegate :name, :email, :to => :approver

Define a method in the User model that raises a RuntimeError with the message "YES, a new user was created!" Raise this error every time a new user is saved.

# models/user.rb
class User < ActiveRecord::Base
  attr_accessible :email, :name
  has_many :documents, :foreign_key => "approver_id"
  after_save :raise_happy_runtime

  def raise_happy_runtime
    raise "YES, a new user was created!"
  end
end