Как настроить ассоциацию has_many, где одна модель имеет два набора идентификаторов jsonb в Ruby on Rails

Я хочу иметь возможность запрашивать игры пользователя, где его user_id находится в движении игр white_user_ids или black_user_ids. Я также хочу иметь возможность запрашивать пользователей игры, где ходы white_user_ids или black_user_ids соответствуют пользователям.

РЕДАКТИРОВАТЬ:

Прежде чем я начну объяснять свой вопрос более подробно, я придумал обходной путь:

class User < ActiveRecord::Base
  def games
    Game.where( [ "moves -> 'black_user_ids' @> '?' OR moves -> 'white_user_ids' @> '?'", self.id, self.id ] )
  end
end

class Game < ActiveRecord::Base
  serialize :moves, HashSerializer
  store_accessor :moves, :white_user_ids, :black_user_ids

  def users
    User.find((self.white_user_ids + self.black_user_ids).uniq)
  end
end

Есть ли что-то неправильное в создании пользовательских методов с именами, которые я хочу, вместо того, чтобы писать has_many ...? Если это хак и плохой, то, пожалуйста, продолжайте читать и не стесняйтесь отвечать.

Первоначальный вопрос:

Вот самая основная версия схемы для этого вопроса:

User
  id

Game
  id
  moves - jsonb
    white_user_ids - integer array
    black_user_ids - integer array

Я создал индекс выражения для обоих user_id:

execute <<-SQL
  CREATE INDEX moves_white_user_ids_on_games ON games USING GIN ((moves->'white_user_ids'));
  CREATE INDEX moves_black_user_ids_on_games ON games USING GIN ((moves->'black_user_ids'));
SQL

Я не знаю, как настроить отношения между пользователями и играми. Очевидно, существует какое-то отношение has_many или, может быть, даже отношение has_and_belongs_to_many. Но я сохраняю все данные, которые мне понадобятся для создания ассоциации, в таблице игр, перемещает столбец jsonb.

Примеры:

<User id: 1>
<User id: 5>
<User id: 6>
<User id: 11>
<User id: 17>
<User id: 20>
<User id: 23>
<User id: 35>
<User id: 76>
<User id: 89>
<User id: 93>

<Game id: 1, moves: {"black_user_ids"=>[88],
                     "white_user_ids"=>[23]}>
<Game id: 2, moves: {"black_user_ids"=>[6, 1, 11, 76, 17, 23],
                     "white_user_ids"=>[93, 89, 1, 35, 20, 5, 6]}>
<Game id: 3, moves: {"black_user_ids"=>[76, 68, 20, 96, 19, 3],
                     "white_user_ids"=>[82, 48, 29, 37, 20, 74]}>
<Game id: 4, moves: {"black_user_ids"=>[82],
                     "white_user_ids"=>[74, 16]}>
<Game id: 5, moves: {"black_user_ids"=>[22, 41, 25, 78, 50],
                     "white_user_ids"=>[24, 10, 99, 26, 1, 4]}>

Пользовательские ассоциации/области:

User.find(1).games вернет игры [2, 5], любую уникальную игру, в которой либо black_user_ids, либо white_user_ids имеют свой user_id.

User.find(1).black_games вернет игру [2], любую игру, в которой black_user_ids имеет свой user_id.

User.find(1).white_games вернет игры [2, 5], любую игру, в которой white_user_ids имеет свой user_id.

Ассоциации/области игры:

Game.find(2).users вернет пользователей [1, 5, 6, 11, 17, 20, 23, 35, 76, 89, 93], любого уникального пользователя в его black_user_ids или white_user_ids.

Game.find(3).black_users вернет пользователей [3, 19, 20, 68, 76, 96], любого пользователя в его black_user_ids.

Game.find(4).white_users вернет пользователей [16, 74], любого пользователя в его white_user_ids.


person Eric    schedule 25.08.2015    source источник
comment
spacevatican.org/2008/5 /6/ надеюсь, это поможет вам   -  person Aditya Shanker Tagirisa    schedule 26.08.2015


Ответы (1)


Вы можете сделать это с помощью полиморфных ассоциаций.

http://guides.rubyonrails.org/association_basics.html#polymorphic-associations

В этом случае таблица ходов будет иметь идентификатор и черный или белый цвет. Затем вы можете связать это с игрой и запросить ходы черных или белых.

person dinomix    schedule 28.08.2015