Archive for August, 2012

Ruby on Rails / Active Record Notes Basic 5 – Callbacks & Observers

Thursday, August 30th, 2012

Six common Active Record callbacks, 1 less:

before_create

after_create

before_save

after_save

before_destroy

after_destroy

after_initialize

example, add this to your model, and it will never be created…:

def before_create

false

end

Observers

$ rails generate observer Comment

class CommentObserver < ActiveRecord::Observer

def after_create(comment)

puts “We will notify the author”

end

end

config/application.rb:

config.active_record.observers = :comment_observer

Ruby on Rails Active Record Notes 4 Validations

Wednesday, August 29th, 2012

Build-in

:message example :message=>’too long’

: on example : on=>:create

validates :title, :presence => true

validates :email, :uniqueness => true, :length => { :within => 5..50 }

// other :length options //

:minimum

:maximum

:is

:within

:allow_nil

:too_long

:too_short

:wrong_length

:message

 

Format of an attribute (regex)

:format => { :with => /^[^@][\w.-][+@][\w.-]+[.][a-z]{2,4}$/i }

validates :password, :confirmation => true

 

other validations

:numbericality

:inclusion

:exclusion

:acceptance

 

custom error validation (example for model, add to errors Object)

def article_should_be_published

errors.add(:article_id, “is not published yet”) if article && !article.published?

end

this custom method is invoked prior to save via the validate method, different from validates, full model class example:

class Comment < ActiveRecord::Base

attr_accessible :article_id, :body, :email, :name
belongs_to :article

validates :name, :email, :body, :presence => true
validate :article_should_be_published

def article_should_be_published

errors.add(:article_id, “is not published yet”) if article && !article.published?

end

end

RoR Active Record notes 3

Wednesday, August 29th, 2012

Finding

Article.where(:title=>’Advanced Active Record’)

SQL Fragment

Article.where(“title = ‘Advanced Active Record'”)

Article.where(“created_at > ’23-03-2010′ OR body NOT LIKE ‘%model%'”)

Article.where(“created_at > ’23-03-2010′ AND body NOT LIKE ‘%model%'”)

Array Condition Syntax

Article.where(“published_at < ?”, Time.now)

Inspect the rendered SQL

Article.where(“published_at < ?”, Time.now).to_sql

Article.where(“created_at = ? OR body LIKE ?”, Article.last.created_at, ‘model’)

Print directly to the log file

logger.debug “This…”

logger.warn “all environments…”

Association Proxies

User.first.articles.all (example)

Other Finder methods

where(conditions)

order example Article.order(“title ASC”)

limit example Article.limit(1) example Article.order(“title DESC”).limit(2)

joins

includes

 

Default Scope

class Category < ActiveRecord::Base

attr_accessible :name
has_and_belongs_to_many :articles

default_scope order(‘categories.name’) // you can pass any finder method to default_scope

end

Random! – EXIT rails console!! – Cntrl D

more scope examples for your model

scope :published, where(“articles.published_at IS NOT NULL”)
scope :draft, where(“articles.published_at IS NULL”)
scope :recent, lambda { published.where(“articles.published_at > ?”, 1.week.ago.to_date)}
scope :where_title, lambda { |term| where(“articles.title LIKE ?”, “%#{term}%”)}

Rails Console / Active Record (ORM) Basics (Associations) 2

Tuesday, August 28th, 2012

Associations:

Model -> Article

Table -> articles

foreign key (column in associated table, say comments) to reference this table -> article_id

class methods:

has_one (example: 1 User has 1 Profile)

example:

class User< ActiveRecord::Base

has_one :profile (table profiles has foreign key user_id)

end

class Profile < ActiveRecord::Base

belongs_to :user

end

in console

>>user = User.create(:email=>’user@example.com’,:password=>’secret’)

>>profile = Profile.create(:name=>’John Doe’,:bio=>’Ruby developer’)

>>user.profile = profile

or in one line

>>user.create_profile :name=>’John Doe’, :bio=>’Ruby developer’

methods added by has_one association:

user.profile

user.profile=(profile)

user.profile.nil?

user.build_profile(attributes={}) / not saved

user.create_profile(attributes={}) / saved

common has_one options:

:class_name

:conditions

:foreign_key

: order

:dependent

methods added by has_many and belongs_to associations:

user.articles

user.articles=(articles)

user.articles << article

user.articles.delete(article)

user.articles.empty?

user.articles.size

user.article_ids

user.articles.clear

user.articles.find

user.articles.build(attributes={})

user.articles.create(attributes={})

common has_many options:

:class_name

:conditions

:foreign_key

: order

:dependent

example:

class User < ActiveRecord::Base

attr_accessible :email, :password
has_one :profile
has_many :articles, : order => ‘published_at DESC, title ASC’, :dependent => :destroy

end

has_and_belongs_to_many (habtm)

example: articles to categories

neither ‘belongs_to’ strictly

join table created alphabetical, thus articles_categories

has_and_belongs_to_many :articles

Rails Console / Active Record (Object Relational Mapping) – Basics (CRUD) 1

Tuesday, August 28th, 2012

Console

$rails console

get Model information (Article):

/* inherited from ActiveRecord::Base */

>>Article.column_names

full info:

>>Article

>>Article.methods.size (will return # of available methods!)

ActiveRecord Basics: CRUD

create

>>article = Article.new (create new Model object with constructor)

>>article.new_record? (returns =>true)

>>article.title = ‘blahblah’ (setter)

alternate: >>article = Article.new(:title=>’blahblah’)

>>article (outputs new article and set variables, in this case just title)

>>article.save

>>Article.count (returns 1)

>>article.new_record? (false)

create instead of save, all in one step:

>>Article.create(:title=>’blahblah’)

or

>>attributes = {:title=>’blahblah’}

>>Article.create(attributes)

read

find(:id) / find(:all)  / find(:first) / find(:last)

>>Article.find(3)

>>article = Article.find(3)

>>article.id (returns 3)

>>Article.first

>>Article.last

>>article = Article.all

>>articles.class (returns Array)

>>articles.size (returns integer)

>>articles[0] / >>articles[0].title

>>articles.first.title

loop

>>articles.each{|article| puts article.title}

order, where

>>articles = Article.order(“published_at”) (order return by desired field)

>>Article.where(:title => ‘blahblah’).first

>>Article.where(:title => ‘blahblah’).all

dynamic

find_by_*(cond) – example: find_by_title(‘blahblah’)

find_all_by_*(cond)

find_by_*_and_*(cond1,cond2)

find_all_by_*_and_*(cond1,cond2)

update

>>article = Article.first

>>article.title = ‘notblah’

>>article.save

in one call

>>article = Article.first

>>article.update_attributes(:title=>’notblah’)

delete

  • destroy works on the instance, instantiates the object, finds a single row, then deletes

>>article = Article.last

>>article.destroy

or one line

>>Article.last.destroy

>>Article.destroy(3) // by id

>>Article.destroy([2,3])

  • delete operates on the class, on the table rather than a given row from that table

>>Article.delete(4)

>>Article.delete([5,6])

>>Article.delete_all(“published_at < ‘2001-01-01′”)

check validation

>>article = Article.new

>>article.errors.any? // returns bool

>>article.errors.full_messages // returns specified message

>>article.errors.on(:title)

>>article.errors.size

>>article.valid?