【问题标题】:Validating nested models with ActiveModel::Validations使用 ActiveModel::Validations 验证嵌套模型
【发布时间】:2016-10-02 22:34:34
【问题描述】:

我的应用程序使用带有ActiveModel::Validations 的普通Ruby 类,没有实现ActiveRecord

class Car
  include ::ActiveModel::Validations

  attr_accessor :engine
end

class Engine
  include ::ActiveModel::Validations

  attr_accessor :cylinders
  validates_presence_of :cylinders
end

我希望Car 检查属于ActiveModel::Validations 的嵌套属性,在本例中为engine

car = Car.new
car.engine = Engine.new

car.engine.valid? # => false
car.valid?        # => true
                  # It should return 'false',
                  # because 'engine.cylinders' is 'nil'

获得这种行为的最简单方法是什么?

【问题讨论】:

    标签: ruby-on-rails ruby validation activemodel


    【解决方案1】:

    一种选择是创建自己的验证方法,例如

    class Car
      include ::ActiveModel::Validations
    
      attr_accessor :engine
    
      validate :engine_must_be_valid
    
      def engine_must_be_valid
        errors.add(:base, "Engine is not valid") unless engine.valid?
      end
    end
    

    【讨论】:

    • 我在想也许我想将engine 中的错误嵌套到cars 错误中,但似乎大多数人认为这是一种反模式。这对于我正在处理的基本案例来说似乎已经足够了。
    【解决方案2】:

    我在几乎所有项目中都使用 Gem active_type 来满足类似的要求。项目声明 - 让任何 Ruby 对象像 ActiveRecord 一样嘎嘎作响。项目 github 页面也提供了很好的文档。

    在您的 Gemfile 中,添加:
    gem 'active_type'

    那么,

    class Car < ActiveType::Object  
    
        nests_one :engine
        validates :check_engine
    
        def check_engine
            return true if self.engine.valid?
            false
        end
    end
    
    class Engine < ActiveType::Object
    
        attribute :cylinders, :string
        validates :cylinders, presence: true
    end
    

    现在,

    car = Car.new
    car.engine = Engine.new
    
    car.engine.valid? # => false
    car.valid?        # => false
    

    【讨论】:

      猜你喜欢
      • 2020-02-12
      • 2014-03-20
      • 1970-01-01
      • 2012-12-12
      • 1970-01-01
      • 2021-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多