I am using rails 4 + mongoid 4 beta1.
Product belongs to Category and has dynamic attributes based on category. I validate dynamic attributes with custom method, but its looks ugly. How can i use standart validate methods inside my custom method or there is a better way?
Here is my model(not full):
class Product
include Mongoid::Document
include Mongoid::Attributes::Dynamic
belongs_to :category
before_validation :custom_field_to_datatype
validates :category_id, :presence => true
validate :custom_fields_validator
private
def custom_field_to_datatype
self.category.product_attributes.each do |pr_at|
name = pr_at.name.to_sym
if pr_at.type == 'boolean'
self[name] = self[name].to_bool
elsif pr_at.type == 'integer'
self[name] = self[name].to_i
end
end
end
def custom_fields_validator
max_length = 30
max_integer = 9223372036854775807
min_integer = -9223372036854775807
self.category.product_attributes.each do |pr_at|
name = pr_at.name.to_sym
case pr_at.type
when 'string'
errors.add(name, "Длина строки должна быть не больше #{max_length} символов") if self[name].length > max_length
when 'integer'
if self[name] > max_integer
errors.add(name, "Значение должно быть не больше #{max_integer}")
elsif self[name] < min_integer
errors.add(name, "Значение должно быть не меньше #{min_integer}")
end
end
end
end
end
Personally, I think you should move custom validators out of your model and into its own validator class. You should read this guide, especially the part about custom validator: http://edgeguides.rubyonrails.org/active_record_validations.html#custom-validators
P.s. What you are doing is not wrong though, but it is usually better to extract complex behaviour with only one responsibility, in this case validating product attributes, into its own class. Custom validators are also great for keeping your code dry, because you can use them in any class you like.