PG::UndefinedColumn: ERROR: column courts.user_id does not exist

PG::UndefinedColumn: ERROR: column courts.user_id does not exist

这是我在 运行 测试 this 文件时收到的错误。

当我尝试使用 'destroy' 方法从数据库中删除用户时,错误出现在第 83 行。

This 是有问题的回购及时冻结。

错误:

ActiveRecord::StatementInvalid:
       PG::UndefinedColumn: ERROR:  column courts.user_id does not exist
       LINE 1: SELECT "courts".* FROM "courts" WHERE "courts"."user_id" = $...

我正在尝试通过这种方式将 table 用户与 table 法院联系起来:

如您所见,'Court' 有一个链接到 'users' 的外键,但名为 'administrator'。

我希望'administrator'成为用户的别名,因为将来用户和法院可能会有更多关系:例如'owner'。

我可以看到活动记录正在构建此查询:

SELECT "courts".* FROM "courts" WHERE "courts"."user_id" = $...

如果 Active Record 以这种方式构建查询,也许可以解决这个问题

SELECT "courts".* FROM "courts" WHERE "courts"."administrator_id" = $...

但我不知道该怎么做,也不知道这样做是否谨慎。

也许还有另一种方法可以做到这一点。更整洁的东西,我觉得我没有正确地进行关联。

你推荐什么?

models/user.rb

class User < ActiveRecord::Base
    before_save :format_input
    # extend Devise::Models
    # Include default devise modules        .
    devise  :database_authenticatable,                
            # :validatable,
            # :recoverable,
            # :rememberable,
            # :trackable,             
            # :confirmable,
            # :omniauthable,
            :registerable
    
    # note that this include statement comes AFTER the devise block above
    include DeviseTokenAuth::Concerns::User
    validates :first_name, presence: true, length: { in: 1..20 }
    validates :last_name, presence: true, length: { in: 1..20 }
    validates :email, uniqueness: true
    validates_format_of :email, with: /@/
    validates :password, presence: true, length: { in: 8..20 }, :on => :create

    has_many :courts, dependent: :destroy
    
    private

    def format_input
            self.first_name = first_name.downcase.titleize
            self.last_name = last_name.downcase.titleize
            self.email = email.downcase
    end
end

models/court.rb

class Court < ApplicationRecord 

  belongs_to :administrator, :class_name => :user
  validates :name, presence: true, length: { in: 1..20 }
  validates :address, presence: true, length: { in: 1..50 }
  validates :description, presence: true, length: { in: 1..100 }
  validates :description, presence: true, length: { in: 1..100 }

end

问题出在这一行。

has_many :courts, dependent: :destroy

默认情况下,ActiveRecord 假定外键名为 <lowercased_parent_class_name>_id。在这种情况下,当您删除用户时,ActiveRecord 会尝试使用不存在的 user_id 外键删除关联的法院。将 foreign_key 选项传递给 has_many 调用。

has_many :courts, dependent: :destroy, foreign_key: :administrator_id

来自docs

:foreign_key

Specify the foreign key used for the association. By default this is guessed to be the name of this class in lower-case and _id suffixed. So a Person class that makes a has_many association will use person_id as the default :foreign_key.

还有一个问题。您应该在 Court 模型的 belongs_to 调用中将大写的 class 名称作为字符串传递。

belongs_to :administrator, class_name: 'User'

这与问题无关,但您可能想检查是否可以在删除用户记录时删除法院。