简体   繁体   中英

Rails 4 : Amistad gem breaks polymorphic association

I have a user model in which I'm using the Amistad gem . Everything was working fine so far. In my app, I also have a members table which have only 2 fields : user_id and group_id .

Since I need to use this members table to also store communities members, I decided to make it a polymorphic table :

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

To continue, I created a memberable concern that I'm attaching to my groups and communities :

# 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

So far so good, all the associations are working great. However, since my members table will contains Groups and Communities , I need to be able to retreive all the groups I'm belonging to has user. So in my user model, I did :

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

This code itself works fine and when I'm calling user.groups it generate the following query :

SELECT `groups`.* 
FROM `groups` 
INNER JOIN `members` ON `groups`.`id` = `members`.`memberable_id` 
WHERE `members`.`user_id` = 1 
  AND `members`.`memberable_type` = 'Group'

But as I mentionned in the title and above at the beginning, I'm using Amistad gem so I included it :

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

This, breaks my polymorphic association somehow and I don't know why. When calling user.groups , Rails generate me the following query (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'

Note the last line : AND groups.memberable_type = 'Group' . I've tried to look inside the gem without finding why there was any conflict.

Any ideas guys?

EDIT
I forked the gem and tried to hack around. It appear that the gem is using squeel which is exactly the source of this issue.

EDIT 2
Yeeaaahhh, I found a fix. Within my Member model, I used to have :

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

In order to fix the conflict with Squeel , I had to change it by :

class Member < ActiveRecord::Base
  belongs_to :user
  belongs_to :memberable, polymorphic: true, foreign_type: 'members.memberable_type'
end

Well I asked this question a while now but it turned out that the above didn't work. I actually needed to remove Squeel from the friend_model/friends on the Amistad gem .
The forked version that patch it can be found at https://github.com/softmonkeyjapan/amistad

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM