Подтвердить что ты не робот

Custom rails has_many association (через массив pg)

Итак, в основном я хотел бы знать, существует ли какой-то общий подход для определения собственных типов ассоциаций. Некоторые подробности:

У меня есть модель conversations, у которой есть столбец массива PG user_ids. Итак, чтобы получить пользовательские разговоры, мне нужно запустить: select conversations.* from conversations where USER_ID = ANY(conversations.user_ids)

Так как finder_sql и теперь друзья устарели, мне бы очень хотелось знать, что было бы лучшим способом реализовать эту ассоциацию псевдо-has_many?

В настоящее время я просто использую такие методы, как:

 def conversations
   Conversation.where("#{id} = ANY (conversations.users)")
 end

Итак, в основном я собираюсь реализовать свой собственный ActiveRecord::Associations::CollectionAssociation и хотел бы знать, есть ли хорошие ссылки или если вы можете посоветовать, где начать с


4b9b3361

Ответ 1

Как насчет:

Conversation.user.select{ |conversation| conversation.user_ids.include?(params[:id])

Учитывая, что столбец user_ids сериализуется, и текущий идентификатор пользователя передается параметрами [: id]

Основной подход заключается в том, что если у вас есть массив, вы можете проверить, есть ли у него что-то внутри с .include? (что-то). Думая об этом, вы можете использовать метод select для фактического выбора объектов (в этом случае пользователей), имеющих свои идентификаторы внутри этого массива с помощью метода include. Мне ясно?

Скажите, если это сработало...

Ответ 2

Я думаю, вы можете просто поместить код метода в отношение:

has_many :conversations, ->(user) { where("#{user.id} = ANY (conversations.users)") }

В конце концов, это должно быть одно и то же. Ваш метод возвращает отношение, к которому вы можете подключиться. Другой альтернативой может быть что-то вроде:

has_many :conversations, -> { where('users.id IN conversations.users') }

Может потребоваться некоторый финал. Есть ли причина, по которой вы не можете добавить новую таблицу соединений? Идеальным было бы перенести это в таблицу conversations_users. Затем вы можете присоединиться к таблице и использовать ограничения внешнего ключа.

Ответ 3

Вы должны реструктурировать его в справочную таблицу, в которой он хранит разговор_ид и идентификатор_пользователя, после чего вы можете использовать его в соответствии с рекомендациями Rails (https://guides.rubyonrails.org/association_basics.html#the-has-many-through -ассоциация)

Если вы все еще хотите сохранить эту структуру, я предлагаю:

User.where(id: conversion.user_ids) (преобразование является экземпляром таблицы бесед)

Ответ 4

Я предлагаю нормализовать вашу модель, чтобы иметь другую таблицу, которая поддерживает отношения между пользователями и разговорами, например, создавая такую модель, как

UsersConversation

и ваши отношения будут

class User < ApplicationRecord
  has_many :users_conversations, :dependent => :destroy
  has_many :conversations, :through => :users_conversations
end

class Conversation < ApplicationRecord
  has_many :users_conversations, :dependent => :destroy
  has_many :users, :through => :users_conversations
end     

Тогда вы можете легко сделать

#users for each specific conversation
@users = Conversation.find(1).users
#conversations for each specific user
@conversations = User.find(1).conversations

Если вы не хотите сохранить тот же путь или массив, вы можете сделать это как

@users = User.where(:id => Conversation.find(1).user_ids)

если user_ids хранится в виде массива, как [1,10,20], значит, он будет работать нормально и вернет пользователей