(PG::UndefinedColumn:调用时出错 current_user.games

(PG::UndefinedColumn: ERROR when calling current_user.games

我正在尝试调用 current_user.games 并不断收到错误消息:

ActiveRecord::StatementInvalid(PG::UndefinedColumn:错误:列 assignments.user_id 不存在) 第 1 行:..." ON "games"."id" = "assignments"."game_id" WHERE "assignmen...

我相信我的模型设置正确来处理这样的查询,但有些东西告诉我我必须 运行 一个添加用户作为参考的迁移?

型号:

class User < ApplicationRecord
  devise :invitable, :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable, :invitable, invite_for: 2.weeks

  has_many :assignments
  has_many :games, through: :assignments
end
class Game < ApplicationRecord
    has_one :assignment, dependent: :destroy
    has_many :users, through: :assignment

    after_save :create_assignment

    def create_assignment
        Assignment.create(game_id: id)
    end
end
class Assignment < ApplicationRecord
    belongs_to :game
    belongs_to :user

    # belongs_to :assignor, class_name: "User", optional: true

    belongs_to :center_referee, class_name: 'User', optional: true
    belongs_to :assistant_referee_1, class_name: 'User', optional: true
    belongs_to :assistant_referee_2, class_name: 'User', optional: true

    accepts_nested_attributes_for :game    
end

架构:

create_table "assignments", force: :cascade do |t|
    t.integer "game_id"
    t.integer "center_referee_id"
    t.integer "assistant_referee_1_id"
    t.integer "assistant_referee_2_id"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

  create_table "games", force: :cascade do |t|
    t.string "home_team"
    t.string "away_team"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

  create_table "users", force: :cascade do |t|
    t.string "email", default: "", null: false
    t.string "encrypted_password", default: "", null: false
    t.string "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.integer "sign_in_count", default: 0, null: false
    t.datetime "current_sign_in_at"
    t.datetime "last_sign_in_at"
    t.string "current_sign_in_ip"
    t.string "last_sign_in_ip"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.string "first_name"
    t.string "last_name"
    t.string "role"
  end

简短回答:您将无法实现您尝试使用的功能 has_many。至少不是 table 的设计方式。不幸的是,您应该尝试使用 scope


另一方面,有一种不同的方式来设计您的系统。查看新 Assignment。架构:

create_table "assignments", force: :cascade do |t|
  t.integer "game_id"
  t.integer "user_id"
end

型号:

class Assignment < ApplicationRecord
  belongs_to :game
  belongs_to :user
end

class User < ApplicationRecord
  has_many :assignments
  has_many :games, through: :assignments
end

class Game < ApplicationRecord
  has_many :assignments
  has_many :users, through: :assignments
end

您可能想要将 center refereeassistant referee 区分开来。

我不确切知道 User 模型中的 role 列是什么意思,因此我假设您的 role 列与 center/assistant 无关裁判。

如果是这种情况,我会添加一个无符号的 tinyint roleAssignment 并将其用作枚举。所以我的模型是:

class Assignment < ApplicationRecord
  belongs_to :game
  belongs_to :user

  enum role: { center_referee: 0, assistant_referee_1: 1, assistant_referee_2: 2 }

  # in case there must be only a kind of referee for a game:
  validates(:role, uniqueness: { scope: [:game_id] })
end

还有我的架构:

create_table "assignments", force: :cascade do |t|
  t.integer "role", limit: 1, unsigned: true
  t.integer "game_id"
  t.integer "user_id"
end