2016-06-03 2 views
1

Моего приложения использует обычные классы Ruby, с ActiveModel::Validations, без реализации ActiveRecord:валидирующего хеш модели с ActiveModel :: Validations

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' 

Что такое самый простой способ получить это поведение?

ответ

2

Одним из вариантов является создание собственный метод проверки, что-то вроде

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 
+0

Я думал, что, возможно, я хотел, чтобы гнездиться ошибки из 'engine' в 'ошибки автомобиля, но кажется, что большинство людей думает, что это анти-шаблон. Это кажется достаточным для основного случая, с которым я работаю. –

1

Я использую 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