复杂的 Rails 模型/关联

Posted

技术标签:

【中文标题】复杂的 Rails 模型/关联【英文标题】:Complex Rails Models/Associations 【发布时间】:2021-08-17 00:47:10 【问题描述】:

我正在为裁判建立一个分配系统。

问题 我以前问过这个问题/略有不同,但又遇到了麻烦。我基本上有 5 个模型需要链接在一起,我无法在线找到资源来指定/指导我找到要加入 3 个以上表的解决方案。我想我已经确定了它,我可以在控制台中提取我需要的东西,但它似乎无处不在。

简单英语的模型:

    League - 设计可以通过表单登录并上传日程(创建游戏)的用户 Assignor - 设计用户,然后制定该时间表并为比赛分配裁判 裁判员 - 设计分配给比赛的用户 游戏 - 由 League 创建(包含指定的球队、场地、裁判组) 任务 - 在联盟创建游戏时创建

我的模特/协会是:

class Assignor < ApplicationRecord
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable

  has_many :games
  has_many :referees
  has_many :assignments, through: :games
  belongs_to :league
end

class Referee < ApplicationRecord
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable

  belongs_to :assignor
  has_and_belongs_to_many :games
  has_many :assignments, through: :games
end

class Game < ApplicationRecord
  belongs_to :league
  belongs_to :assignor
  has_and_belongs_to_many :referees
  has_one :assignment
end

class Assignment < ApplicationRecord
  belongs_to :assignor
  belongs_to :referee
  belongs_to :game
end

class League < ApplicationRecord
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable

  has_one :assignor
  has_many :games
end

编辑 - 我遇到的实际问题

对于有超过 1 名裁判的作业,我是否需要更改表格以反映这一点?现在表格如下,允许一名裁判,但我需要在一个 Assignment 上最多有 4 名:

create_table "assignments", force: :cascade do |t|
    t.integer "assignor_id", null: false
    t.integer "referee_id", null: false
    t.integer "game_id", null: false
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.index ["assignor_id"], name: "index_assignments_on_assignor_id"
    t.index ["game_id"], name: "index_assignments_on_game_id"
    t.index ["referee_id"], name: "index_assignments_on_referee_id"
  end

我如何对其进行建模以使表格看起来像:

reate_table "assignments", force: :cascade do |t|
    t.integer "assignor_id", null: false
    t.integer "game_id", null: false
    t.integer "center_referee", null: false
    t.integer "assistant_referee_one", null: false
    t.integer "assistant_referee_two", null: false
    t.integer "fourth_official", null: false
  end

创建另一个模型/替换另一个模型并将其命名为“crew_referee”以将裁判与游戏相关联会更好吗?

最终目标 我希望能够让 League 创建一个由 Assignor 分配 RefereesGames 组成的时间表一个作业

我的想法是,基本上我希望能够让用户登录并查看他们各自的游戏作业

【问题讨论】:

你说你遇到了麻烦;您看到的具体问题或错误是什么? 抱歉,忘记添加那部分了。更新了! 【参考方案1】:

一个可能的解决方案是允许用户在每场比赛中创建多个分配,然后他可以分配多个裁判,每个裁判具有不同的角色。

为了反映裁判的角色/类型,您可以在分配表中添加另一列,其中包含有关分配类型的信息(中心,助理,...)

如果您真的希望每场比赛只有一项包含 4 位裁判员的作业,您可以这样做:

class CreateAssignments < ActiveRecord::Migration[6.1]
  def change
    create_table :assignments do |t|
      t.references :assignor, null: false, foreign_key: true
      t.references :game, null: false, foreign_key: true
      t.references :center_referee, null: false, foreign_key:  to_table: :referees 
      t.references :assistant_referee_one, null: false, foreign_key:  to_table: :referees 
      t.references :assistant_referee_two, null: false, foreign_key:  to_table: :referees 
      t.references :fourth_official, null: false, foreign_key:  to_table: :referees 
      t.timestamps
    end
  end 
end

要通过作业访问裁判,您可以在作业模型中添加以下内容:

belongs_to :center_referee, class_name: 'Referee', foreign_key: 'center_referee_id'
belongs_to :assistant_referee_one, class_name: 'Referee', foreign_key: 'assistant_referee_one_id'
...

【讨论】:

这更有意义。我正在考虑将我的模型切换到一个用户模型,然后使用设计角色,但这应该可以正常工作。谢谢!

以上是关于复杂的 Rails 模型/关联的主要内容,如果未能解决你的问题,请参考以下文章

Rails - 视图模型关联

Rails 查询关联的模型范围

Rails 隔离引擎模型关联

Rails 3. 按关联模型排序

在 Rails 中创建对象及其所有关联模型的副本

未创建 Rails 关联模型