如何验证模型,无论它是否有特定的列?

How to validate the model, whether it is having particular column or not?

class Project
  include Listable
       
  listtable(data_attribute: :verified_at)
end

关注

module Listable
  class_methods do
    def listable(data_attribute: :verified_at)
      raise ActiveModel::MissingAttributeError, 
        "Must have a verified_at attribute"  unless respond_to?(:verified_at)
    end
  end
end

在我的 项目模型我有列 verified_at。如果我的 table 中没有 verified_at 列,它应该会引发错误。

但是这里没有正常响应。总是引发错误(甚至 verified_at 也存在)

预期

无论我在我的模型中包含这个问题的什么地方,它都应该检查 verified_at 列是否存在。如果不存在,应该引发错误。

这对我来说没有发生,请给我任何解决方案,在此先感谢

Listable 模块在这里不是绝对必要的。 Rails 附带了开箱即用的 ActiveRecord 验证,像这样的东西可以满足您的需要:

class Project
  validates :verified_at, presence: true
end

然后您可以实例化一个 Project 并检查它是否有效。如果.valid? returns false,则无法保存到数据库:

project = Project.new
=> #<Project:0x00007ff3aec268a8
 id: nil,
 verified_at: nil,
 created_at: nil,
 updated_at: nil>
project.valid?
=> false
project.save!
=> ActiveRecord::RecordInvalid: Validation failed: Verified At can't be blank

project = Project.new(verified_at: Time.zone.now)
=> #<Project:0x00007ff3aec268a8
 id: nil,
 verified_at: Mon, 11 Jan 2021 04:09:24 EST -05:00,
 created_at: nil,
 updated_at: nil>
project.valid?
=> true
project.save!
#  DB query
=> true

一些阅读:https://guides.rubyonrails.org/active_record_validations.html

问题是该模型没有按照您预期的方式respond_to?

Project.respond_to?(:id)
# false

为什么?因为您是在询问 class 本身是否具有 id 属性,该属性仅适用于一个实例。

Project.first.respond_to?(:id)
# true

要解决此问题,您可以利用 Project.column_names 方法,如下所示。

raise ActiveModel::MissingAttributeError, 
    "Must have a verified_at attribute" unless column_names.include?('verified_at')