微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

用于枚举的 i18n-tasks 自定义扫描仪

如何解决用于枚举的 i18n-tasks 自定义扫描仪

我想为 i18n 任务创建一个自定义扫描器,它可以检测在 模型 中声明为 哈希枚举

我的enum 声明模式将永远是这样的:

class Conversation < ActiveRecord::Base
  enum status: { active: 0,archived: 1},_prefix: true
  enum subject: { science: 0,literature: 1,music: 2,art: 3 },_prefix: true
end

枚举将始终声明为散列,并且始终具有数字散列值,并且始终在声明的末尾具有选项 _prefix: true。散列中可以有任意数量的值。

我的自定义扫描仪目前如下所示:

require 'i18n/tasks/scanners/file_scanner'
class ScanModelEnums < I18n::Tasks::Scanners::FileScanner
  include I18n::Tasks::Scanners::OccurrenceFromPosition

  # @return [Array<[absolute key,Results::Occurrence]>]
  def scan_file(path)
    text = read_file(path)
    text.scan(/enum\s([a-zA-Z]*?):\s\{.*\W(\w+):.*\},_prefix: true$/).map do |prefix,attribute|
      occurrence = occurrence_from_position(
          path,text,Regexp.last_match.offset(0).first)
      model = File.basename(path,".rb") #.split('/').last
      name = prefix + "_" + attribute
      ["activerecord.attributes.%s.%s" % [model,name],occurrence]
    end
  end
end

I18n::Tasks.add_scanner 'ScanModelEnums'

然而,这只是返回每个散列的最后一个元素:

  • activerecord.attributes.conversation.status_archived
  • activerecord.attributes.conversation.subject_art

如何返回每个散列的所有元素?我想看到这样的结果:

  • activerecord.attributes.conversation.status_active
  • activerecord.attributes.conversation.status_archived
  • activerecord.attributes.conversation.subject_science
  • activerecord.attributes.conversation.subject_literature
  • activerecord.attributes.conversation.subject_music
  • activerecord.attributes.conversation.subject_art

作为参考,i18n-tasks github 存储库提供了一个 example of a custom scanner

它使用的文件扫描器类可以在 here 中找到。

解决方法

这有效:

def scan_file(path)
  result = []
  text = read_file(path)

  text.scan(/enum\s([a-zA-Z]*?):\s\{(.*)},_prefix: true$/).each do |prefix,body|
    occurrence = occurrence_from_position(path,text,Regexp.last_match.offset(0).first)

    body.scan(/(\w+):/).flatten.each do |attr|
      model = File.basename(path,".rb")
      name = "#{prefix}_#{attr}" 
      result << ["activerecord.attributes.#{model}.#{name}",occurrence]
    end
  end
  result
end

它类似于您的“答案”方法,但使用正则表达式获取“{...}”之间的所有内容,然后使用另一个正则表达式获取每个枚举键名称。

您的“答案”版本引发错误的可能原因是它实际上返回的是一个三维数组,而不是两个:

  1. 外部 .map 是所有迭代的数组。
  2. 每次迭代返回retval,这是一个数组。
  3. retail 的每个元素都是一个由 ['key',occurrence] 对组成的数组。
,

这不是答案,这只是我做的另一个尝试,它输出一个二维数组而不是单个数组:

require 'i18n/tasks/scanners/file_scanner'
class ScanModelEnums < I18n::Tasks::Scanners::FileScanner
  include I18n::Tasks::Scanners::OccurrenceFromPosition

  # @return [Array<[absolute key,Results::Occurrence]>]
  def scan_file(path)
    text = read_file(path)
    text.scan(/enum\s([a-zA-Z]*?):\s\{(.*)\},_prefix: true/).map do |prefix,attributes|
      retval = []
      model = File.basename(path,".rb")
      names = attributes.split(",").map!{ |e| e.strip; e.split(":").first.strip }
      names.each do |attribute|
        pos = (Regexp.last_match.offset(0).first + 8 + prefix.length + attributes.index(attribute))
        occurrence = occurrence_from_position(
            path,pos)
        name = prefix + "_" + attribute
        # p "================"
        # p type
        # p message
        # p ["activerecord.attributes.%s.%s" % [model,name],occurrence]
        # p "================"
        retval.push(["activerecord.attributes.%s.%s" % [model,occurrence])
      end
      retval
    end
  end
end

I18n::Tasks.add_scanner 'ScanModelEnums'

然而,这给了我检测到的第二个属性的错误:

gems/i18n-tasks-0.9.34/lib/i18n/tasks/scanners/results/key_occurrences.rb:48:in `each': undefined method `path' for ["activerecord.attributes.conversation.status_archived",Occurrence(app/models/project.rb:3:32:98::)]:Array (NoMethodError)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。