📖

Rails の Inflectorはどこで書かれているか?

2024/05/16に公開

Rails の Inflectorって何?

単数を複数形に、複数形を単数形にしてくれるモノ

rails console で試してみる

$ rails c
Loading development environment (Rails 7.1.3.2)
irb(main):001> "post".pluralize
=> "posts"
irb(main):002> "posts".singularize
=> "post"

Ruby on Railsの公式リファレンス(APIドキュメント)を見てみる

https://api.rubyonrails.org/classes/String.html

See ActiveSupport::Inflector.pluralize を見てみる

on GitHubからコードを見てみる

activesupport/lib/active_support/inflector/methods.rb
require "active_support/inflections"
...
    # Returns the plural form of the word in the string.
    #
    # If passed an optional +locale+ parameter, the word will be
    # pluralized using rules defined for that language. By default,
    # this parameter is set to <tt>:en</tt>.
    #
    #   pluralize('post')             # => "posts"
    #   pluralize('octopus')          # => "octopi"
    #   pluralize('sheep')            # => "sheep"
    #   pluralize('words')            # => "words"
    #   pluralize('CamelOctopus')     # => "CamelOctopi"
    #   pluralize('ley', :es)         # => "leyes"
    def pluralize(word, locale = :en)
      apply_inflections(word, inflections(locale).plurals, locale)
    end
...
    # Applies inflection rules for +singularize+ and +pluralize+.
    #
    # If passed an optional +locale+ parameter, the uncountables will be
    # found for that locale.
    #
    #   apply_inflections('post', inflections.plurals, :en)    # => "posts"
    #   apply_inflections('posts', inflections.singulars, :en) # => "post"
    def apply_inflections(word, rules, locale = :en)
        result = word.to_s.dup

        if word.empty? || inflections(locale).uncountables.uncountable?(result)
          result
        else
          rules.each { |(rule, replacement)| break if result.sub!(rule, replacement) }
          result
        end
      end
...
activesupport/lib/active_support/inflections.rb
require "active_support/inflector/inflections"
...
module ActiveSupport
  Inflector.inflections(:en) do |inflect|
    inflect.plural(/$/, "s")
    inflect.plural(/s$/i, "s")
    inflect.plural(/^(ax|test)is$/i, '\1es')
    inflect.plural(/(octop|vir)us$/i, '\1i')
    inflect.plural(/(octop|vir)i$/i, '\1i')
    inflect.plural(/(alias|status)$/i, '\1es')
    inflect.plural(/(bu)s$/i, '\1ses')
    inflect.plural(/(buffal|tomat)o$/i, '\1oes')
    inflect.plural(/([ti])um$/i, '\1a')
    inflect.plural(/([ti])a$/i, '\1a')
    inflect.plural(/sis$/i, "ses")
...

まとめ:コードを追ってみて

activesupport/lib/active_support/inflections.rb
    inflect.plural(/$/, "s")
    inflect.plural(/s$/i, "s")
    inflect.plural(/^(ax|test)is$/i, '\1es')

上記コードで正規表現でパターンにマッチする英単語を置換していることが分かった。

Discussion