Rails has_many通过条件,构建新的

时间:2012-08-28 11:52:35

标签: ruby-on-rails ruby-on-rails-3 has-many-through

我的用户和组织都有一个加入模型UsersOrganisation。用户可能是组织的管理员 - 如果是,则is_admin布尔值为true。

如果我在数据库中手动设置is_admin布尔值,Organisations.admins就像我期望的那样工作。

在控制台中,我可以执行Organisation.first.users << User.first并按照我的预期创建一个organisations_users条目。

但是,如果我执行Organisation.first.admins << User.last,则会创建普通用户,而不是管理员,即连接表上的is_admin布尔值未正确设置。

除了直接在连接表中创建条目外,有没有其他方法可以做到这一点?

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

3 个答案:

答案 0 :(得分:5)

您始终可以覆盖&lt;&lt;协会方法:

has_many :admins do

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

end

(代码尚未检查)

答案 1 :(得分:2)

has_many :through<<运算符有一些曲折。但你可以像在@Erez的回答一样超载它。

我的方法是使用范围(我将OrganisationsUsers重命名为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

现在我创建了这样的新管理员:

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

我喜欢的范围是你在会员类中定义“会员类型”,组织本身根本不需要关心会员类型。

<强>更新

现在你可以做到

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

答案 2 :(得分:1)

您可以尝试下面的组织模型代码。

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