rubyonrails:has_和_属于_许多继承子类的连接吗

omhiaaxx  于 2021-09-29  发布在  Java
关注(0)|答案(1)|浏览(323)

我试图通过RubyonRails中的多对多关系连接两个类(会话和用户)。我对它们进行了设置,并添加了一个名为conversations\u custom\u users的连接表来连接它们,它开始工作了。一旦我们需要从另一个用户模型继承我们的用户模型,在用户对象中设置对话就失败了,并且正在寻找父类的连接表。
我的类和会话迁移如下所示(我没有修改多对多关系的用户迁移):

class CustomUser < Spree::User
   serialize :resources, Array
   has_and_belongs_to_many :conversations, :foreign_key => :conversation_ids, class_name: 'Conversation'
end

class Conversation < ApplicationRecord
    has_and_belongs_to_many :receiver, :foreign_key => :receiver_id, class_name: 'CustomUser'
end

class CreateConversations < ActiveRecord::Migration[6.1]
   def change
      create_table :conversations do |t|
         t.timestamps
      end

      create_table :conversations_custom_users, id: false do |t|
         t.belongs_to :conversation, foreign_key: 'conversation_id', index: true
         t.belongs_to :custom_user, foreign_key: 'receiver_id', index: true
       end
    end
end

我想我不需要添加另一个名为conversations\u spree\u users的表,但我也尝试添加了一个。这并没有解决问题,因为rails当时正在寻找一个spree\u user\u id字段。我还尝试将spree\u user\u id字段添加到conversations\u spree\u users表中,但它不会迁移,因为它是一个重复的列名!
我想我在ruby中遗漏了一些关于多对多关系或继承或两者兼而有之的东西。如果有人能帮我解决这个问题,我会非常感激。

yws3nbqq

yws3nbqq1#

您可以使用多态关联来构建多对多关联,这种方法的好处是,对于所有用户的层次结构继承,您只能使用一个联接表。

class CreateConversationals < ActiveRecord::Migration[6.1]
 def change
  create_table :conversationals do |t|
   # ...
   t.references :contributor, polymorphic: true, null: false
   t.integer :conversation_id
   t.timestamps
  end
 end
end

class Conversational < ApplicationRecord
  belongs_to :contributor, polymorphic: true
  belongs_to :conversation
end

class Conversation < ApplicationRecord
 has_many :conversationals, :foreign_key => :conversation_id
 has_many :custom_users, :through => :conversationals, :source => :contributor, :source_type => 'CustomUser'
 has_many :other_users, :through => :conversationals, :source => :contributor, :source_type => 'OtherUser'
end

class CustomUser < Spree::User
 has_many :conversationals, as: :contributor
 has_many :conversations, :through => :conversationals, :as => :contributor
end

# i assume you use STI

class OtherUser < CustomUser
end

然后

user1 = CustomUser.create(...)
user2 = OtherUser.create(...)
conversation = Conversation.create(...)
conversational1 = Conversational.create(..., conversation_id: conversation.id, contributor: user1)
conversation1 = Conversational.create(...,  conversation_id: conversation.id, contributor: user2)

# many-to-many

user1.conversations
user2.conversations
conversation.custom_users
conversation.other_users

相关问题