如何设置一个has_many关联,其中一个模型在Ruby on Rails中有两组jsonb id

时间:2015-08-25 21:43:19

标签: ruby-on-rails ruby-on-rails-4 associations has-many jsonb

我希望能够查询用户的游戏,其中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_ids创建了一个表达式索引:

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中的任何用户。

1 个答案:

答案 0 :(得分:0)

您可以使用多态关联来完成此操作。

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

移动表将具有id并键入黑色或白色。然后,您可以将其与游戏相关联,并查询黑色移动或白移动。