31. - common options -
:autosave
• No declaration (default)
: new children are saved when their parent
is saved
• :autosave => true
: all children is saved, no matter whether
they are new records
• :autosave => false
: any children is not saved
ROR Lab.
32. - common options -
:autosave
class Post
has_one :author, :autosave => true
end
has_one
post = Post.find(1)
post.title # => "The current global position of migrating ducks"
post.author.name # => "alloy"
post.title = "On the migration of ducks"
post.author.name = "Eloy Duran"
post.save
post.reload
post.title # => "On the migration of ducks"
post.author.name # => "Eloy Duran"
post.author.mark_for_destruction
post.author.marked_for_destruction? # => true
id = post.author.id
Author.find_by_id(id).nil? # => false
post.save
post.reload.author # => nil
Author.find_by_id(id).nil? # => true
http://api.rubyonrails.org/classes/ActiveRecord/AutosaveAssociation.html
ROR Lab.
33. - common options - :autosave
has_many
class Post
has_many :comments # :autosave option is no declared
end
post = Post.new(:title => 'ruby rocks')
post.comments.build(:body => 'hello world')
post.save # => saves both post and comment
post = Post.create(:title => 'ruby rocks')
post.comments.build(:body => 'hello world')
post.save # => saves both post and comment
post = Post.create(:title => 'ruby rocks')
post.comments.create(:body => 'hello world')
post.save # => saves both post and comment
class Post
has_many :comments, :autosave => true
end
post = Post.create(:title => 'ruby rocks')
post.comments.create(:body => 'hello world')
post.comments[0].body = 'hi everyone'
post.save # => saves both post and comment, with 'hi everyone' as body
post.comments.last.mark_for_destruction
post.comments.last.marked_for_destruction? # => true
post.comments.length # => 2
id = post.comments.last.id
Comment.find_by_id(id).nil? # => false
post.save
post.reload.comments.length # => 1
Comment.find_by_id(id).nil? # => true
ROR Lab.
34. - common options -
:class_name
class Order < ActiveRecord::Base
belongs_to :customer, :class_name => "Patron"
end
ROR Lab.
35. - common options -
:conditions
class Order < ActiveRecord::Base
belongs_to :customer, :conditions => "active = 1"
end
ROR Lab.
36. - common options -
:foreign_key
class Order < ActiveRecord::Base
belongs_to :customer, :class_name => "Patron",
:foreign_key => "patron_id"
end
ROR Lab.
37. - common options -
:include
class LineItem < ActiveRecord::Base
belongs_to :order, :include => :customer
end
class Order < ActiveRecord::Base
belongs_to :customer
has_many :line_items
end
class Customer < ActiveRecord::Base
has_many :orders
end
ROR Lab.
38. - common options -
:readonly
class Customer < ActiveRecord::Base
has_many :orders, :readonly => true
end
ROR Lab.
39. - common options -
:select
class Order < ActiveRecord::Base
belongs_to :customer,
:select => "name, profile, group_id"
end
ROR Lab.
40. - common options -
:validate
class Order < ActiveRecord::Base
belongs_to :customer, :validate => true
end
ROR Lab.
41. Common
has_ Options
has_one / has_many
• :as
• :order* (also, included in HABTM)
• :primary_key
• :source
• :source_type
• :through
ROR Lab.
42. - common has_ options -
:as
class Picture < ActiveRecord::Base
belongs_to :imageable, :polymorphic => true
end
class Employee < ActiveRecord::Base
has_many :pictures, :as => :imageable
end
class Product < ActiveRecord::Base
has_many :pictures, :as => :imageable
end
ROR Lab.
43. - common has_ options -
:order
class Post < ActiveRecord::Base
has_many :comments, :order => ”updated_at”
end
•also, in HABTM
ROR Lab.
44. - common has_ options -
:primary_key
class Order < ActiveRecord::Base default
belongs_to :customer,
:primary_key => "id",
:foreign_key => "customer_id"
class Order < ActiveRecord::Base
belongs_to :customer, :class_name => "Patron",
:primary_key => "civil_no",
:foreign_key => "patron_id"
ROR Lab.
45. - common has_ options -
:source & :source_type
class Tag < ActiveRecord::Base
has_many :taggings, :dependent => :destroy
has_many :books, :through => :tagings, :source => :taggable, :source_type => "Book"
has_many :movies, :through => :tagings, :source => :taggable, :source_type => "Movie"
end
class Tagging < ActiveRecord::Base
belongs_to :taggable, :polymorphic => true
belongs_to :tag
end
class Book < ActiveRecord::Base
has_many :taggings, :as => :taggable
has_many :tags, :through => :taggings
end
class Movie < ActiveRecord::Base
has_many :taggings, :as => :taggable
has_many :tags, :through => :taggings
end
• http://www.brentmc79.com/posts/polymorphic-many-to-many-associations-in-rails
ROR Lab.
46. - common has_ options -
:through
class Supplier < ActiveRecord::Base
has_one :account
has_one :account_history, :through => :account
end
class Account < ActiveRecord::Base
belongs_to :supplier
has_one :account_history
end
class AccountHistory < ActiveRecord::Base
belongs_to :account
end
ROR Lab.
48. - common _many options -
:finder_sql
class Person < ActiveRecord::Base
has_many :subscribers,
:class_name => "Person",
:finder_sql => Proc.new {
%Q{
SELECT DISTINCT *
FROM people p, post_subscriptions ps
WHERE ps.post_id = #{id} AND ps.person_id = p.id
ORDER BY p.first_name
}
}
ROR Lab.
49. - common _many options -
:counter_sql
class Person < ActiveRecord::Base
has_many :subscribers,
:class_name => "Person",
:counter_sql => Proc.new {
%Q{
SELECT DISTINCT *
FROM people p, post_subscriptions ps
WHERE ps.post_id = #{id} AND ps.person_id = p.id
ORDER BY p.first_name
}
}
ROR Lab.
50. - common _many options -
:extend
association proxy(or interface)
class Customer < ActiveRecord::Base
has_many :orders do
def find_by_order_prefix(order_number)
find_by_region_id(order_number[0..2])
end
end
ROR Lab.
51. - common _many options -
:extend
module FindRecentExtension
def find_recent
where("created_at > ?", 5.days.ago)
end
end
class Customer < ActiveRecord::Base
has_many :orders, :extend => FindRecentExtension
end
class Supplier < ActiveRecord::Base
has_many :deliveries, :extend => FindRecentExtension
ROR Lab.
52. - common _many options -
:extend
class Customer < ActiveRecord::Base
has_many :orders,
:extend => [FindRecentExtension, FindActiveExtension]
end
ROR Lab.
53. - common _many options -
*
3 AP accessors
• proxy_association.owner
• proxy_association.reflection
• proxy_association.target
AP* : Association Proxy
ROR Lab.
54. - common _many options -
:group
class Customer < ActiveRecord::Base
has_many :line_items,
:through => :orders,
:group => "orders.id"
end
ROR Lab.
60. - special options for HABTM -
:association_foreign_key
class User < ActiveRecord::Base
has_and_belongs_to_many :friends,
:class_name => "User",
:foreign_key => "this_user_id",
:association_foreign_key => "other_user_id"
many-to-many self join
ROR Lab.
61. - special options for HABTM -
:delete_sql
class Developer < ActiveRecord::Base
has_and_belongs_to_many :active_projects,
:join_table => 'developers_projects',
:delete_sql =>
"DELETE FROM developers_projects WHERE active=1
AND developer_id = #{id}
AND project_id = #{record.id}"
end
ROR Lab.
62. - special options for HABTM -
:insert_sql
class Developer < ActiveRecord::Base
has_and_belongs_to_many :active_projects,
:join_table => 'developers_projects',
:insert_sql =>
"INSERT INTO developers_projects
VALUES(#{id},#{record.id})"
end
ROR Lab.
63. - special options for HABTM -
:join_table
class Category < ActiveRecord::Base
has_and_belongs_to_many :products,
:join_table => “cats_prods”
end
class Product < ActiveRecord::Base
has_and_belongs_to_many :categories,
:join_table => “cats_prods”
default join table => “categories_products”
ROR Lab.
64. Association Callbacks
• in the lifecycle of a collection
• before_add
• after_add
• before_remove
• after_remove
ROR Lab.
65. Association Callbacks
class Customer < ActiveRecord::Base
has_many :orders, :before_add => :check_credit_limit
def check_credit_limit(order)
...
end
end
class Customer < ActiveRecord::Base
has_many :orders,
:before_add =>
[:check_credit_limit, :calculate_shipping_charges]
def check_credit_limit(order)
...
end
def calculate_shipping_charges(order)
...
end
ROR Lab.