#ruby-on-rails #rails-activerecord #rails-migrations
#ruby-on-rails #рельсы-activerecord #rails-миграции #rails-activerecord
Вопрос:
Давний слушатель, вызывающий в первый раз. Я пытаюсь создать две ассоциации между одними и теми же таблицами базы данных, комнатами чата и пользователями. Пока у меня есть отношение has_many through, при котором в комнате чата много пользователей через сообщения. Эта часть работает нормально. Что я хочу сделать, это создать вторую таблицу объединения, которая соединяет комнаты чата с пользователями, через таблицу объединения, называемую Chatroom_players. Итак, я бы хотел, чтобы Chatroom.first.users приводил мне пользователей через таблицу объединения сообщений, а Chatroom.first.players — всех из таблицы объединения chatroom_players. Причина, по которой я хочу этого, заключается в том, что я могу поддерживать присутствие пользователя, даже если пользователь не написал никаких сообщений в чате, также чтобы пользователь мог покинуть комнату, но сохранить свои сообщения в чате.
Вот что у меня пока что не работает:
chatroom.rb:
class Chatroom < ApplicationRecord
has_many :messages, dependent: :destroy
has_many :users, through: :messages
has_many :chatroom_players
has_many :users, through: :chatroom_players
end
message.rb:
class Message < ApplicationRecord
belongs_to :chatroom
belongs_to :user
validates :content, presence: true, length: {minimum: 2, maximum: 200}
end
chatroom_player.rb
class ChatroomPlayer < ApplicationRecord
belongs_to :chatroom
belongs_to :user
end
user.rb
class User < ApplicationRecord
has_many :messages, dependent: :destroy
has_many :chatrooms, through: :messages
has_many :chatroom_players
has_many :chatrooms, through: :chatroom_players
end
миграция chatroom_players:
class AddChatroomPlayers < ActiveRecord::Migration[5.0]
def change
create_table :chatroom_players do |t|
t.references :user, index: true, foreign_key: true, null: false
t.references :chatroom, index: true, foreign_key: true, null: false
t.boolean :creator, default: false
t.timestamps null: false
end
end
end
Ответ №1:
Вам нужно использовать разные имена для ассоциаций:
class Chatroom < ApplicationRecord
has_many :messages, dependent: :destroy
has_many :users, through: :messages
has_many :chatroom_players
# this is a separate association to users through the
# chatroom_players table.
has_many :participants,
through: :chatroom_players,
source: :user, # what association on chatroom_players to use
class_name: 'User' # since it cannot be deduced automatically
end
Комментарии:
2. Отличный ответ, спасибо! Еще одна вещь, которую мне нужно было сделать, что я и сделал в вашем стиле, это связать комнаты чата с пользователями как игры, так что теперь у пользователей есть игры и комнаты чата, а в комнатах чата есть пользователи и игроки.
3. has_many : games, через: :chatroom_players, source: : chatroom, class_name: «Чат»