Reputation: 5201
My application uses plain Ruby classes with ActiveModel::Validations
, without implementing ActiveRecord
:
class Car
include ::ActiveModel::Validations
attr_accessor :engine
end
class Engine
include ::ActiveModel::Validations
attr_accessor :cylinders
validates_presence_of :cylinders
end
I would like Car
to check the nested attributes that are of ActiveModel::Validations
, in this case engine
.
car = Car.new
car.engine = Engine.new
car.engine.valid? # => false
car.valid? # => true
# It should return 'false',
# because 'engine.cylinders' is 'nil'
What's the easiest way to get this behavior?
Upvotes: 7
Views: 2270
Reputation: 29
I use Gem active_type in almost all my projects for similar requirements. Project statement - Make any Ruby object quack like ActiveRecord. Project github page provides good documentation as well.
in your Gemfile, add:
gem 'active_type'
Then,
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
Now,
car = Car.new
car.engine = Engine.new
car.engine.valid? # => false
car.valid? # => false
Upvotes: 0
Reputation: 7779
One option is creating your own validation method, something like
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
Upvotes: 3