4

I've got users and organisations with a join model UsersOrganisation. Users may be admins of Organisations - if so the is_admin boolean is true.

If I set the is_admin boolean by hand in the database, Organisations.admins works as I'd expect.

In the console, I can do Organisation.first.users << User.first and it creates an organisations_users entry as I'd expect.

However if I do Organisation.first.admins << User.last it creates a normal user, not an admin, ie the is_admin boolean on the join table is not set correctly.

Is there a good way of doing this other than creating entries in the join table directly?

class User < ActiveRecord::Base

  has_many :organisations_users
  has_many :organisations, :through => :organisations_users

end

class Organisation <  ActiveRecord::Base

  has_many :organisations_users
  has_many :users, :through => :organisations_users
  has_many :admins, :through => :organisations_users, :class_name => "User", 
            :source => :user, 
            :conditions => {:organisations_users => {:is_admin => true}}

end

class OrganisationsUser < ActiveRecord::Base

  belongs_to :organisation
  belongs_to :user

end
4

3 回答 3

5

You can always override the << method of the association:

has_many :admins do

  def <<(user)
    user.is_admin = true
    self << user
  end

end

(Code has not been checked)

于 2012-08-28T12:34:44.657 回答
2

there are some twists with the has_many :through and the << operator. But you could overload it like in @Erez answer.

My approach to this is using scopes (I renamed OrganisationsUsers to Memberships):

class User < ActiveRecord::Base

  has_many :memberships
  has_many :organisations, :through => :memberships

end

class Organisation <  ActiveRecord::Base
  has_many :memberships
  has_many :members, :through => :memberships, :class_name => 'User', :source => :user

  # response to comment:
  def admins 
    memberships.admin
  end
end

class Memberships < ActiveRecord::Base

  belongs_to :organisation
  belongs_to :user

  scope :admin, where(:is_admin => true)
end

Now I create new admins like this:

Organisation.first.memberships.admin.create(:user => User.first)

What I like about the scopes is that you define the "kind of memberships" in the membership class, and the organisation itself doesn't have to care about the kinds of memberships at all.

Update:

Now you can do

Organisation.first.admins.create(:user => User.first)

于 2012-08-28T12:42:10.577 回答
1

You can try below code for organization model.

class Organisation < ActiveRecord::Base

  has_many :organisations_users
  has_many :organisations_admins, :class_name => "OrganisationsUser", :conditions => { :is_admin => true }

  has_many :users,  :through => :organisations_users
  has_many :admins, :through => :organisations_admins, :source => :user

end
于 2012-08-28T12:33:10.797 回答