我有一个使用Amistad gem的用户模型。到目前为止一切正常。在我的应用程序中,我还有一个members
只有 2 个字段的表:user_id
和group_id
。
由于我需要使用此members
表来存储社区成员,因此我决定将其设为多态表:
class CreateMembers < ActiveRecord::Migration
def change
create_table :members do |t|
t.integer :user_id
t.string :memberable_type
t.integer :memberable_id
end
end
end
为了继续,我提出了一个memberable
关注我的团体和社区的问题:
# app/models/concerns/memberable.rb
module Memberable
extend ActiveSupport::Concern
included do
has_many :members_users, as: :memberable, class_name: Member
has_many :members, through: :members_users, source: :user
end
end
# app/models/group.rb
class Group < ActiveRecord::Base
include Memberable
belongs_to :user
end
# app/models/community.rb
class Community < ActiveRecord::Base
include Memberable
belongs_to :user
end
到目前为止一切顺利,所有协会都运作良好。但是,由于我的members
表将包含Groups
and Communities
,我需要能够检索我所属的所有组有用户。所以在我的用户模型中,我做了:
class User < ActiveRecord::Base
has_many :members
has_many :groups, through: :members, source: :memberable, source_type: 'Group'
has_many :created_groups, class_name: Group
end
此代码本身工作正常,当我调用user.groups
它时会生成以下查询:
SELECT `groups`.*
FROM `groups`
INNER JOIN `members` ON `groups`.`id` = `members`.`memberable_id`
WHERE `members`.`user_id` = 1
AND `members`.`memberable_type` = 'Group'
但正如我在标题和开头提到的那样,我使用的是Amistad gem,所以我将它包括在内:
class User < ActiveRecord::Base
include Amistad::FriendModel
has_many :members
has_many :groups, through: :members, source: :memberable, source_type: 'Group'
has_many :created_groups, class_name: Group
end
这以某种方式破坏了我的多态关联,我不知道为什么。调用时user.groups
,Rails 为我生成以下查询(不好的一个):
SELECT `groups`.*
FROM `groups`
INNER JOIN `members` ON `groups`.`id` = `members`.`memberable_id`
WHERE `members`.`user_id` = 1
AND `groups`.`memberable_type` = 'Group'
注意最后一行:AND groups.memberable_type = 'Group'
。我试图查看宝石内部,但没有找到任何冲突的原因。
有什么想法吗?
编辑
我分叉了宝石并试图破解。看来gem正在使用squeel
这正是这个问题的根源。
编辑 2
Yeeaaahhh,我找到了解决方法。在我的Member
模型中,我曾经有:
class Member < ActiveRecord::Base
belongs_to :user
belongs_to :memberable, polymorphic: true
end
为了解决与 的冲突Squeel
,我必须通过以下方式更改它:
class Member < ActiveRecord::Base
belongs_to :user
belongs_to :memberable, polymorphic: true, foreign_type: 'members.memberable_type'
end