ruby-on-rails 如何在mobility gem中使用验证?

ubof19bj  于 2023-08-08  发布在  Ruby
关注(0)|答案(2)|浏览(94)

我正试图在我的移动性驱动的应用程序中添加验证,我有点困惑

I18n.available_locales.each do |locale|
    validates :"name_#{locale}", presence: true, uniqueness: {scope: :animal_type}
end

字符串
而且效果很好。但在我的上一个项目中,它根本不起作用。关于如何执行验证有什么想法?我的配置如下:

Mobility.configure do
  plugins do
    backend :container
    active_record
    reader
    writer
    backend_reader
    query
    cache
    presence
    locale_accessors
  end
end


UPD:我已经确定了我的问题-这是因为, uniqueness: {scope: :animal_type}。是否可以在类似类型的确认中使用移动性?

nnt7mjpx

nnt7mjpx1#

当你使用uniqueness验证器时,它会对数据库进行查询,以确保记录还没有被占用,你会得到这样的查询:
假设您有Animal模型

SELECT 1 AS one FROM "animals" WHERE "animals"."name_en" = "Cat" AND "animals"."animal_type" = "some_type" LIMIT 1

字符串
当然,在animals表中没有name_en字段,这就是为什么会出现错误
要存档,你必须编写你自己的验证器

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


然后在你的模型中执行以下操作:

I18n.available_locales.each do |locale|
  validates :"name_#{locale}", presence: true, custom: true
end

rkkpypqq

rkkpypqq2#

@Yurii Stefaniuk的回答很有帮助。但是如果你使用的是带有移动性的动作文本(https://github.com/sedubois/mobility-actiontext/),那么属性名称是不同的,你可能需要使用这样的东西来代替:

def translation_exists?(record, attribute)
    attribute, locale = attribute.to_s.split('_')
    record.class.joins(:plain_text_translations).exists?(
      { action_text_rich_texts: {
          locale: locale,
          body: record.send(attribute)
        } }
    )
  end

字符串

相关问题