Rails 4:Amistad gem打破了多态关联

时间:2014-06-30 21:41:44

标签: ruby-on-rails gem associations amistad

我有一个用户模型,其中我使用Amistad gem。到目前为止一切都很好。 在我的应用中,我还有一个members表,其中只有两个字段:user_idgroup_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表格将包含GroupsCommunities,因此我需要能够检索我所属的所有具有用户的群组。所以在我的用户模型中,我做了:

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会生成以下查询(BAD ONE):

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

1 个答案:

答案 0 :(得分:0)

我现在问了这个问题,但事实证明上述情况不起作用。实际上我需要从 Amistad gem 上的Squeel中移除friend_model/friends
可以在https://github.com/softmonkeyjapan/amistad

找到修补它的分叉版本