我有一个使用globalize gem和globalize-accessors gem的已翻译字段的模型,用于为本地化名称字段提供name_en
,name_zh_hk
等本地化属性。
例如:
class Person < ActiveRecord::Base
translates :name
globalize_accessors: locales: [:en, :"zh-HK"], attributes: [:name]
# problem is:
validates :name, presence: true, uniqueness: true
end
所以现在name_en和name_zh_hk可以正确获取和设置相应语言环境中的值。
但是,validates :name
仅验证Person模型中的名称字段。我还想验证中文输入的唯一性。
简而言之,想要一种(简单)方法来验证name_en和name_zh_hk的唯一性
**我有一个提交name_en和name_hk的表单。
答案 0 :(得分:2)
在person.rb
模型文件的末尾({1}}之外,添加以下内容:
class Person ... end
答案 1 :(得分:1)
您必须这样做
class Person < ActiveRecord::Base
translates :name
globalize_accessors: locales: [:en, :"zh-HK"], attributes: [:name]
class Translation
validates :name, presence: true, uniqueness: true
end
end
答案 2 :(得分:0)
我可能会对你对独特范围的询问感到困惑:
validates :name, uniqueness: {scope: :blah}
具体而言,您可能希望拥有“PersonName”模型。
PERSONNAME
名称|当地的|为person_id
人has_many :names
然后:
validates :name, uniqueness: { scope: :person_id }
这样,如果他们为HK输入与以下名称相同的名称:en它将无效。
答案 3 :(得分:0)
使用以下代码解决。
<强>模型强>
# /app/models/category.rb
...
I18n.available_locales.each do |locale|
validates :"name_#{locale}", presence: true, length: { maximum: 5 }, uniqueness: true
end
<强>验证强>
# config/initializers/associated_translations_uniqueness_validator.rb
require 'active_record'
require 'active_record/validations/uniqueness.rb'
ActiveRecord::Validations::UniquenessValidator.class_eval do
def validate_each_with_associated_translations(record, attribute, value)
klass = record.class
if klass.translates? && !klass.translated?(attribute) && klass.globalize_attribute_names.include?(attribute)
attribute_parts = attribute.to_s.rpartition('_')
raw_attribute = attribute_parts.first.to_sym
locale = attribute_parts.last.to_sym
finder_class = klass.translation_class
table = finder_class.arel_table
relation = build_relation(finder_class, table, raw_attribute, value).and(table[:locale].eq(locale))
relation = relation.and(table[klass.reflect_on_association(:translations).foreign_key].not_eq(record.send(:id))) if record.persisted?
translated_scopes = Array(options[:scope]) & klass.translated_attribute_names
untranslated_scopes = Array(options[:scope]) - translated_scopes
untranslated_scopes.each do |scope_item|
scope_value = record.send(scope_item)
reflection = klass.reflect_on_association(scope_item)
if reflection
scope_value = record.send(reflection.foreign_key)
scope_item = reflection.foreign_key
end
relation = relation.and(find_finder_class_for(record).arel_table[scope_item].eq(scope_value))
end
translated_scopes.each do |scope_item|
scope_value = record.send(scope_item)
relation = relation.and(table[scope_item].eq(scope_value))
end
if klass.unscoped.with_translations.where(relation).exists?
record.errors.add(attribute, :taken, options.except(:case_sensitive, :scope).merge(:value => value))
end
else
validate_each_without_associated_translations(record, attribute, value)
end
end
alias_method_chain :validate_each, :associated_translations
end