I'm trying to add validations to my mobility-powered application and i'm confused a little.Earlier I've used code like this
I18n.available_locales.each do |locale|
validates :"name_#{locale}", presence: true, uniqueness: {scope: :animal_type}
end
And it worked fine. But in my last project it doesn't work at all. Any ideas how to perform validations? My config is below:
Mobility.configure do
plugins do
backend :container
active_record
reader
writer
backend_reader
query
cache
presence
locale_accessors
end
end
UPD: I've identified my problem - it is because of , uniqueness: {scope: :animal_type}
. Is it possible to use mobility with similar type of validations?
When you use uniqueness
validator it uses query to the database to ensure that record haven't already taken and you get this query:
Let's assume you have Animal
model
SELECT 1 AS one FROM "animals" WHERE "animals"."name_en" = "Cat" AND "animals"."animal_type" = "some_type" LIMIT 1
And of course there is no name_en
field in the animals
table that is why you have an error
To archive this you have to write your own validator
class CustomValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
if translation_exists?(record, attribute)
record.errors.add(attribute, options[:message] || :taken)
end
end
private
def translation_exists?(record, attribute)
attribute, locale = attribute.to_s.split('_')
record.class.joins(:string_translations).exists?(
mobility_string_translations: { locale: locale, key: attribute },
animals: { animal_type: record.animal_type }
)
end
end
And then in your model do next:
I18n.available_locales.each do |locale|
validates :"name_#{locale}", presence: true, custom: true
end