4

我正在构建一个自定义验证方法以在我的 rails 应用程序中使用。我要构建的验证器类型将模型中调用验证器的列与其他表中的列进行比较。以下是一个代码示例,说明了我正在尝试构建的验证器的模式。

module ActiveModel
    module Validations
        module ClassMethods
            # example: validate_a_column_with_regard_to_other_tables :column, tables: { table_one: :some_column }
            def validate_a_column_with_regard_to_other_tables(*attr_names)
                validates_with WithRegardToOtherTablesValidator, _merge_attributes(attr_names)
            end
        end

        class WithRegardToOtherTablesValidator < EachValidator
            def validate_each(record, attribute, value)
                # compare record, attribute or value to all records that match table: :column in :tables
            end
        end
    end
end

可以使用应用程序和架构中存在的模型对此进行测试。但是,这不是测试验证器的好方法,因为它会将验证器描述为依赖于它不依赖的模型。

我能想到的唯一其他方法是在测试中创建一组模型模型。

class ValidateModel < BaseModel
    validate_a_column_with_regard_to_other_tables :column, :tables { compare_to_model: :some_column }
end

class CompareToModel < BaseModel
    attr_accessor :some_column
end

但是,无法验证 :column 是否与 :compare_to_model 中的 :some_column 有关,因为 :compare_to_model 不是架构的一部分。

如何在测试中创建一个作为模式一部分的模拟模型?或者有没有更好的方法来测试这样的自定义验证器功能?

4

1 回答 1

1

如果您正在使用rspec,您可以设置如下内容:

before(:all) do
  ActiveRecord::Migration.create_table :compare_to_model do |t|
    t.string :some_column
    t.timestamps
  end
end

it "validates like it should" do
  ...
end

after(:all) do
  ActiveRecord::Migration.drop_table :compare_to_model
end
  • before(:all)关于它的一个注释是“全局”设置,因此数据会从一个it到另一个持续存在,您可能希望it用一个事务包装每个事务并在之后将其回滚,或者改为使用一个before(:each)可以清理表的事务。
于 2014-01-14T13:36:00.540 回答