naming.rb 2.2 KB
Newer Older
1 2
require 'active_support/inflector'

J
Joshua Peek 已提交
3 4
module ActiveModel
  class Name < String
5
    attr_reader :singular, :plural, :element, :collection, :partial_path
6
    alias_method :cache_key, :collection
7

8 9
    def initialize(klass)
      super(klass.name)
10
      @klass = klass
11 12
      @singular = ActiveSupport::Inflector.underscore(self).tr('/', '_').freeze
      @plural = ActiveSupport::Inflector.pluralize(@singular).freeze
13
      @element = ActiveSupport::Inflector.underscore(ActiveSupport::Inflector.demodulize(self)).freeze
14
      @human = ActiveSupport::Inflector.humanize(@element).freeze
15 16
      @collection = ActiveSupport::Inflector.tableize(self).freeze
      @partial_path = "#{@collection}/#{@element}".freeze
17
    end
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35

    # Transform the model name into a more humane format, using I18n. By default,
    # it will underscore then humanize the class name (BlogPost.model_name.human #=> "Blog post").
    # Specify +options+ with additional translating options.
    def human(options={})
      return @human unless @klass.respond_to?(:lookup_ancestors) &&
                           @klass.respond_to?(:i18n_scope)

      defaults = @klass.lookup_ancestors.map do |klass|
        klass.model_name.underscore.to_sym
      end

      defaults << options.delete(:default) if options[:default]
      defaults << @human

      options.reverse_merge! :scope => [@klass.i18n_scope, :models], :count => 1, :default => defaults
      I18n.translate(defaults.shift, options)
    end
36
  end
R
Rizwan Reza 已提交
37 38 39 40
  
  # == Active Model Naming
  #
  # Creates a +model_name+ method on your object.
41 42 43 44
  # 
  # To implement, just extend ActiveModel::Naming in your object:
  # 
  #   class BookCover
45
  #     extend ActiveModel::Naming
46 47 48 49 50 51 52 53
  #   end
  # 
  #   BookCover.model_name        #=> "BookCover"
  #   BookCover.model_name.human  #=> "Book cover"
  # 
  # Providing the functionality that ActiveModel::Naming provides in your object
  # is required to pass the ActiveModel Lint test.  So either extending the provided
  # method below, or rolling your own is required..
J
Joshua Peek 已提交
54 55 56 57
  module Naming
    # Returns an ActiveModel::Name object for module. It can be
    # used to retrieve all kinds of naming-related information.
    def model_name
58
      @_model_name ||= ActiveModel::Name.new(self)
J
Joshua Peek 已提交
59
    end
60
  end
61
  
62
end