Reputation: 15736
I have a lot of models with many different attributes that are shared between them, and so I have to validate them all and thats where I am having a problem. If I group all attributes that are always used together and put their validations in a separated module, I end up with like 20 modules, which just doesnt seem right... Also I thought about putting attrs validations in only like 2-3 modules grouping them logically, like one module for location attrs, other is for options and etc and additing to all of them the IF condition the following way:
validates :city,
presence: true,
length: {minimum: 5},
if: Proc.new {|p| p.respond_to?(:city)}
and it looks like it works but repeating this condition to every validation method is just even more wrong than having a bunch of modules, so the question is, how do I do it right?
Edit: Example: Imagine you have 3 models: Car, Truck and Bicycle and their attrs are:
Car -> attr_1, attr_3
Truck -> attr_2, attr_3
Bicycle -> attr_1, attr_2
and so u can put validation of every attr to its module and include it to the clases that have this attribute, so u dont have to repeat it... ( thats where I end up with 20 modules) or u can create only one module with 3 validations like the following:
validates :attr_1, length: {minimum: 2}, if: Proc.new {|p| p.respond_to?(:attr_1)}
validates :attr_2, presence: true, if: Proc.new {|p| p.respond_to?(:attr_2)}
validates :attr_3, inclusion: {in: 1..5}, if: Proc.new {|p| p.respond_to?(:attr_3)}
which seems to be more ugly ... So I need to find some compromise here ...
Upvotes: 0
Views: 1134
Reputation: 32933
Remember you're just using ruby code here, there's nothing magical going on. So you can do a loop:
[:attr1, :attr2, :attr3].each do |att|
validates att, presence: true, length: {minimum: 5}, if: Proc.new {|p| p.respond_to?(att)}
end
Upvotes: 1
Reputation: 27747
Ok... so you have multiple models with a set of related attribute (and validations) on them>
some options are:
if there really are 20 different groups of things... then create 20. But if groups of these things are always together in every model that uses them... you can put them into one spot together (and use code like Max's suggestion to make it shorter to read)
Upvotes: 1