无法获得适用于 has_many 的动态条件:通过(+ 所有权)

Can't get dynamic condition working for has_many :through (+ ownership)

仍在寻找解决方案 (2/24/16)

我的用户模型具有 has_many :through 与组的关系。所以用户有很多组,组有很多用户,但我也想建立一个用户对组的所有权,谁可以做出最终决定。

思路是user.groups是用户所属的所有组,user.managed_groups是用户owns/manages的所有组。如果有人知道更好的构造方法,将不胜感激!

下面的代码是我现在的设置。

用户组模型(加入table)

class UserGroup < ActiveRecord::Base
  belongs_to :user
  belongs_to :group
end

群模型

class Group < ActiveRecord::Base
  has_many :user_groups
  has_many :members, :through => :user_groups, :class_name => "User", :source => :user
  ...

组迁移

class CreateGroups < ActiveRecord::Migration
  def change
    create_table :groups do |t|
      t.integer :user_id, :null => false, :default => 0
      t.string :name, :null => false
      t.timestamps null: false
    end
    add_index :groups, :user_id
  end
end

用户模型

class User < ActiveRecord::Base
  has_many :user_groups
  has_many :groups, :through => :user_groups
  has_many :managed_groups ,-> { where(groups: { user_id: @id }) },
                  through: :user_groups, class_name: "Group", source: :group, 
                  dependent: :destroy
 ...

就是不行....

@user = FactoryGirl.create :user
@group = FactoryGirl.create :group
@group.user_id = @user.id
@group.members << @user
@group.save
@user.reload

结果是 @user.all_managed_groups 完全是空的,但 @user.groups 不是。

我也尝试过:

def all_managed_groups
  groups.where("groups.user_id = ?", id)
end

def all_managed_groups
  Group.find_by_user_id(id)
end

def all_managed_groups
  Group.where("groups.user_id = ?", id)
end 

执行上面的测试代码后,这些都是return一个空关联代理

有效但愚蠢的方法

has_many :managed_groups, class_name: "Group",
                  dependent: :destroy

然后将用户创建的每个新组附加到他们的 managed_groups

我会按照以下方式去做:

class Group < ActiveRecord::Base
  belongs_to :owner, class_name: "User", foreign_key: "user_id"
  has_many :memberships, as: :memberable
  has_many :users, through: :memberships
end

用户

class User < ActiveRecord::Base
  has_many :memberships
  has_many :groups, through: :memberships, source: :memberable, source_type: "Group"
  ...
end

多态关联

class Membership < ActiveRecord::Base
  belongs_to :user
  belongs_to :memberable, polymorphic: true
  ...
end

如果您需要允许用户与任何其他模型关联的成员资格,这还允许 Membership 灵活地适应未来。

希望对您有所帮助!

后续编辑

class User < ActiveRecord::Base
  has_many :managed_groups, foreign_key: "user_id", class: Group

  has_many :user_groups
  has_many :groups, through: :user_groups
end

class Group < ActiveRecord::Base
  belongs_to :user
  has_many :user_groups
end

class UserGroup < ActiveRecord::Base
  belongs_to :user
  belongs_to :group
end

user = User.create(name: "David")
group = Group.create(user_id: user.id, name: "Dayton Ruby")
user.managed_groups => [#<Group id: 1, user_id: 1, name: "Dayton Ruby">]
user.groups => [] (I have not added this user to the UserGroup join table yet)

# adding user as a group member (separate from ownership)
user << groups 
user.groups => [#<Group id: 1, user_id: 1, name: "Dayton Ruby">]

如果您希望要求所有者是组的成员(相对于手动设置),您还可以考虑向您的用户组添加 roleadmin 等字段加入 table。这将允许您添加逻辑来确定哪个组成员可以管理该组。

希望跟进对一些人有所帮助。