Rails: organizations that have admins and moderators and users
Existing models:
class Organization < ActiveRecord::Base
has_many :admins
has_many :users, :through => :admins
class User < ActiveRecord::Base
has_many :admins
has_many :organizations, :through => :admins
No sweat. @org.users
returns a list of admin users.
Now I need to add another role: moderators. I can't add another table in the middle (since an association can only have one target).
A friend suggested I make moderators polymorphic. I read up on that in the Rails Guides, but not sure how to implement it here.
I tried this:
class Moderator < ActiveRecord::Base
belongs_to :modable, :polymorphic => true
end
...and then add this to my User and Organization models:
has_many :moderators, :as => :modable
Technically this works, however, I can't get my users out of this. I tried to add a user_id
column to the Moderator table, but without the association, Rails doesn't want to grab it:
> @org.moderators.joins(:users)
ActiveRecord::ConfigurationError: Association named 'users' was not found; perhaps you misspelled it?
Any help is greatly appreciated. Thanks!
UPDATE:
Ended up with this (note: moderator is called a "network user"):
class Organization < ActiveRecord::Base
has_many :roles
has_many :u开发者_C百科sers, :through => :roles
has_many :admin_roles, :conditions => {:role_type => "AdminRole"}
has_many :admins, :through => :admin_roles, :source => "user", :class_name => 'User'
has_many :network_user_roles, :conditions => {:role_type => "NetworkUserRole"}
has_many :network_users, :through => :network_user_roles, :source => "user", :class_name => 'User'
# This all lives in one table; it has a organization_id, user_id, and special_role_type columns
class Role
belongs_to :organization
belongs_to :user
end
class AdminRole < Role
end
class NetworkUserRole < Role
end
class UserRole < Role
end
I think you're looking for something more like
class Organization < ActiveRecord::Base
has_many :users
has_many :admins
has_many :moderators
has_many :admin_users, :through => :admins, :class_name=>"User"
has_many :moderator_users, :through => :admins, :class_name=>"User"
class Admin < ActiveRecord::Base
has_many :organizations
belongs_to :user
class Moderator < ActiveRecord::Base
has_many :organizations
belongs_to :user
class User < ActiveRecord::Base
has_many :organizations
has_many :admins
has_many :moderators
Basically, it doesn't really make sense for admins to be the bridge between Organizations and Users (or vice versa). An org has admins, and an org has users, and an org has moderators. While a user has admins (in the sense that some users are admins), a user's relationship to the organization shouldn't be through admin, especially for a user who isn't themselves an admin.
An even better approach, I think, would be to add a new model, something like OrganizationRole, that would join an Organization and a Role (such as admin or moderator). That way, when somebody shows up and announces that organizations have to have a secretary, or a webmaster, or whatever, you don't have to modify all of your existing models.
I'm not sure I understand what you are doing here but...It looks to me like you would want:
class Organization < ActiveRecord::Base
has_many :users
has_many :admins, :through => :users
has_many :moderators, :through => :users
精彩评论