Created
August 14, 2008 15:04
-
-
Save joshuaclayton/5439 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This is useful if you need to get a subclassed model through a has_many :through association | |
# Just iterate through each user type you want available and create a named_scope. It sounds | |
# repetitive since you can just call Subclass.all to return those results, but if it's a | |
# :through association, it becomes harder to grab | |
# | |
# For example, let's say I've got a handful of different user subclasses, and I've got | |
# magazines and subscriptions. I want to, on a subscription, find all users of a certain | |
# subclass. Adding named scopes to a user is much easier than iterating through the array to | |
# find all users whose type matches whichever. | |
# | |
# For example, the 'old' way to grab a subclass: | |
# Magazine.first.users.find_all {|u| u.is_a?(Client) } | |
# | |
# The more correct way would be to do something like this: | |
# Magazine.first.users.clients | |
# | |
# This would then use SQL to generate the filter instead of relying on Ruby's iterators to return | |
# results (which is obviously a lot faster, especially if the type column is indexed (which it | |
# should be) and your result sets are large. Plus, it reads a lot better. | |
# | |
# And although you could potentially put this on the Magazine model, it then makes the Magazine | |
# model much too intimate with the types of users. Bad form. | |
class User < ActiveRecord::Base | |
TYPES = %w(Admin Manager Client).freeze | |
User::TYPES.each do |type| | |
class_eval <<-EOV | |
named_scope :#{type.tableize}, :conditions => ["users.user_type = ?", "#{type}"] | |
EOV | |
end | |
has_many :subscriptions | |
has_many :magazines, :through => :subscriptions | |
end | |
class Subscription < ActiveRecord::Base | |
belongs_to :user | |
belongs_to :magazine | |
end | |
class Magazine < ActiveRecord::Base | |
has_many :subscriptions | |
has_many :users, :through => :subscriptions | |
# possible (but bad) way to grab user types, since any :through association would need all these (and it's not DRY | |
# has_many :clients, :through => :subscriptions, :source => :user, :conditions => "user_type = 'Client'" | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment