Rails与同一个类和连接表有很多关系

时间:2017-03-11 14:09:21

标签: ruby-on-rails activerecord

我想在two userschats之间建立关系。 Chatinviteeparticipant,两者都是User类型。

假设我的示例中的SchemaChat模型是正确的,我错过了relationships模型中的User。这是我尝试过很多东西的地方,但最终总是收到错误。基本上我想要实现的是从用户的角度来看:

User.first.chats # => returning all chats which are referencing the user as either invitee or participant。 基本上这应该返回与User模型中的chats方法相同。

我想User模型中应该有两个关系:

class User
  has_many :chats
  has_many :chatpartners, through: :chats
end
但是,那些不起作用。我想问题是我正在使用User模型两次。其他两个解决方案效果不佳(可能在多个方面有误):

class User
  has_many :chats, ->(id) { where("invitee_id = ? OR participant_id = ?", id, id) }

  has_and_belongs_to_many :chatpartners,
                      class_name: "User",
                      join_table: "chats",
                      foreign_key: :invitee_id,
                      association_foreign_key: :participant_id
end

我想如果我得到正确的关系,这些事情会自动发挥作用:

Chat.first.invitee # => returning the User referenced by invitee_id

Chat.first.participant # => returning the User referenced by participant_id

User.first.chats.users # => returning the users referenced by the chat

这是我到目前为止所拥有的:

用户模型

class User < ApplicationRecord
  def chats
    Chat.where("invitee_id = ? OR participant_id = ?", id, id)
  end
end

聊天模式

class Chat < ApplicationRecord
  belongs_to :invitee, foreign_key: :invitee_id, class_name: "User"
  belongs_to :participant, foreign_key: :participant_id, class_name: "User"
end

模式

ActiveRecord::Schema.define(version: 20170311085652) do
  enable_extension "plpgsql"

  create_table "chats", force: :cascade do |t|
    t.integer  "invitee_id"
    t.integer  "participant_id"
    t.datetime "created_at",     null: false
    t.datetime "updated_at",     null: false
  end

  create_table "users", force: :cascade do |t|
    t.datetime "created_at",                null: false
    t.datetime "updated_at",                null: false
  end
end

如果我忘记提及任何有意义的事情,请告诉我。谢谢你的帮助。

1 个答案:

答案 0 :(得分:0)

将设置User这样的一种方式:

class User < ApplicationRecord
  # same as the method you have now
  def chats
    Chat.where("invitee_id = ? OR participant_id = ?", id, id)
  end

  def chat_partners
    User.where(id: chats.pluck(:invitee_id, :participant_id).flatten.uniq.reject { |i| i == self.id })
  end
end