Active Record Relationship Design Patterns 11

Posted by sbecker Fri, 20 Jan 2006 06:30:00 GMT

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
end

E-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
end

Roles 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
end

Mailing Lists:

class MailingList < ActiveRecord::Base
  has_many :subscribers
end

class Subscriber < ActiveRecord::Base
  belongs_to :mailing_list
end

Surveys / 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
end

Hierarchical Content Management:

class Page < ActiveRecord::Base
  acts_as_tree
  acts_as_list :scope => :parent
end

Blogs:

class BlogEntry < ActiveRecord::Base
  has_many :comments, :dependent => true, :order => "created_at ASC"
end

class Comment < ActiveRecord::Base
  belongs_to :blog_entry
end

Social 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
end

Any major ones I’m missing here?

Comments

Leave a response

  1. Avatar
    Anthony Rudgick Fri, 20 Jan 2006 09:28:51 GMT
    nice little helpful list of relationships! kudos. i'm sure these will come in handy to quite a few people.
  2. Avatar
    iphan Wed, 01 Feb 2006 17:49:51 GMT
    the Hierarchical Content Management does not allow multiple parents. The design pattern missing from your list is the Direct Acyclic Graph: a directed tree with multiple inheritance.
  3. Avatar
    Scott Wed, 22 Feb 2006 01:56:49 GMT
    iphan - sounds cool, care to share that one?
  4. Avatar
    Philip Fri, 05 May 2006 02:54:55 GMT
    Hello, I came across this page when searching about RoR association patterns. I am a newbie and it seems to me that there are quite some limitations on the available associations. For example, in your "Roles Based Access Control" example: 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 end Say user1 created a new role, supposedly containing no one yet user1.roles role1 After this assignment, user1 owns role1 but role1 automatically adds user1 as its member. This, semantically, is probably fine as the application logic works well when checking for authorization. But what if I am user1 and now want to edit only my own roles -- roles that I create but not belong to? It looks to me that this common pattern will render it impossible to find only roles I own/create (and excluding those that I belong to.) Any comments and thoughts? Thanks, Philip
  5. Avatar
    scott Wed, 17 May 2006 21:50:41 GMT
    phillip - you're thinking more at the application level, not at the database/relational level. what roles a user belongs to is different from what roles a user creates. two separate things. if you want to track who creates the role, you can make a created_by field and set it to the ID of the user who creates the role. in the Role model class, you can setup a belongs_to association like this: belongs_to :creator, :class_name = "User", :foreign_key = "created_by" then you'll always have a record of who created the role and can provide that list to the user: Role.find_by_created_by(this_user_id)
  6. Avatar
    Dave Mon, 06 Aug 2007 03:59:44 GMT

    “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.

  7. Avatar
    Dead Sea Products Sat, 12 Jan 2008 15:04:21 GMT

    Just the cheat sheet I was looking for. Cheers mate.

  8. Avatar
    Dead Sea Products Sat, 12 Jan 2008 15:04:34 GMT

    Just the cheat sheet I was looking for. Cheers mate.

  9. Avatar
    Play Blackjack On Line Wed, 13 Feb 2008 05:16:48 GMT

    GREAT! I just fall in love with Ruby more and more with each passing day (and tech posts like this :))

  10. Avatar
    Reliance Relocation Sat, 15 Mar 2008 21:39:20 GMT

    There are many articles about ruby and seo already, but I guess another wouldn’t hurt as different point of views can just contribute.

    I’ve read this one lately which has some nice tips – http://ruby.dzone.com/news/seo-tips-ruby-rails

  11. Avatar
    BU Versicherung Wed, 20 Aug 2008 12:03:47 GMT

    You know any good open source CMS based on ruby?

Comments