Active Record Relationship Design Patterns 7
In the world of web applications, eventually you’ve seen it all, and you start to see the same relational patterns occur over and over. To help out the newbies, here’s a list of various relationships (in Ruby on Rails syntax) that we see all the time.
Can you think of any more common relationship patterns?
Customer Relationship Management
class Company < ActiveRecord::Base
has_many :contacts
end
class Contact < ActiveRecord::Base
belongs_to :company
endE-Commerce
class Category < ActiveRecord::Base
has_many :products
end
class Product < ActiveRecord::Base
belongs_to :category
end
class Order < ActiveRecord::Base
has_many :line_items
end
class LineItem < ActiveRecord::Base
belongs_to :product
belongs_to :order
endRoles Based Access Control
class User < ActiveRecord::Base
has_and_belongs_to_many :roles
end
class Roles < ActiveRecord::Base
has_and_belongs_to_many :users
has_and_belongs_to_many :permissions
end
class Permission < ActiveRecord::Base
has_and_belongs_to_many :roles
endMailing Lists:
class MailingList < ActiveRecord::Base
has_many :subscribers
end
class Subscriber < ActiveRecord::Base
belongs_to :mailing_list
endSurveys / Questionaires / Quizzes:
class Survey < ActiveRecord::Base
has_many :questions
has_many :responses
end
class Question < ActiveRecord::Base
belongs_to :survey
has_many :choices
end
class Choice < ActiveRecord::Base
belongs_to :question
end
class Response < ActiveRecord::Base
belongs_to :survey
has_many :response_choices
end
class ResponseChoice < ActiveRecord::Base
belongs_to :response
belongs_to :question
belongs_to :choice
endHierarchical Content Management:
class Page < ActiveRecord::Base
acts_as_tree
acts_as_list :scope => :parent
endBlogs:
class BlogEntry < ActiveRecord::Base
has_many :comments, :dependent => true, :order => "created_at ASC"
end
class Comment < ActiveRecord::Base
belongs_to :blog_entry
endSocial Networking:
(from: wiki.rubyonrails.com)
class User < ActiveRecord::Base
has_and_belongs_to_many :users,
:join_table => 'users_known_users',
:foreign_key => 'known_user_id',
:association_foreign_key => 'user_id',
:after_add => :create_reverse_association,
:after_remove => :remove_reverse_association
def known_users
self.users
end
private
def create_reverse_association(associated_user)
associated_user.known_users << self unless associated_user.known_users.include?(self)
end
def remove_reverse_association(associated_user)
associated_user.known_users.delete(self) if associated_user.known_users.include?(self)
end
endAny major ones I’m missing here?
“Blogs” is actually a generic “Container/Contained” pattern. I came across this page looking for info on implementing this type of pattern for a personal aggregator I’m putting together in rails, and this is the same pattern I’m using, e.g. Feed has_many :item, Item belongs_to :feed, etc.
You know any good open source CMS based on ruby?