diff options
author | Gonçalo Silva <goncalossilva@gmail.com> | 2011-03-24 17:21:17 +0000 |
---|---|---|
committer | Gonçalo Silva <goncalossilva@gmail.com> | 2011-03-24 17:21:17 +0000 |
commit | 9887f238871bb2dd73de6ce8855615bcc5d8d079 (patch) | |
tree | 74fa9ff9524a51701cfa23f708b3f777c65b7fe5 /activemodel/lib/active_model/naming.rb | |
parent | aff821508a16245ebc03510ba29c70379718dfb7 (diff) | |
parent | 5214e73850916de3c9127d35a4ecee0424d364a3 (diff) | |
download | rails-9887f238871bb2dd73de6ce8855615bcc5d8d079.tar.gz rails-9887f238871bb2dd73de6ce8855615bcc5d8d079.tar.bz2 rails-9887f238871bb2dd73de6ce8855615bcc5d8d079.zip |
Merge branch 'master' of https://github.com/rails/rails
Diffstat (limited to 'activemodel/lib/active_model/naming.rb')
-rw-r--r-- | activemodel/lib/active_model/naming.rb | 68 |
1 files changed, 55 insertions, 13 deletions
diff --git a/activemodel/lib/active_model/naming.rb b/activemodel/lib/active_model/naming.rb index b74d669f0a..eb9b847509 100644 --- a/activemodel/lib/active_model/naming.rb +++ b/activemodel/lib/active_model/naming.rb @@ -1,19 +1,25 @@ require 'active_support/inflector' +require 'active_support/core_ext/hash/except' +require 'active_support/core_ext/module/introspection' module ActiveModel class Name < String - attr_reader :singular, :plural, :element, :collection, :partial_path + attr_reader :singular, :plural, :element, :collection, :partial_path, :route_key, :param_key alias_method :cache_key, :collection - def initialize(klass) + def initialize(klass, namespace = nil) super(klass.name) + @unnamespaced = self.sub(/^#{namespace.name}::/, '') if namespace + @klass = klass - @singular = ActiveSupport::Inflector.underscore(self).tr('/', '_').freeze + @singular = _singularize(self).freeze @plural = ActiveSupport::Inflector.pluralize(@singular).freeze @element = ActiveSupport::Inflector.underscore(ActiveSupport::Inflector.demodulize(self)).freeze @human = ActiveSupport::Inflector.humanize(@element).freeze @collection = ActiveSupport::Inflector.tableize(self).freeze @partial_path = "#{@collection}/#{@element}".freeze + @param_key = (namespace ? _singularize(@unnamespaced) : @singular).freeze + @route_key = (namespace ? ActiveSupport::Inflector.pluralize(@param_key) : @plural).freeze end # Transform the model name into a more humane format, using I18n. By default, @@ -30,35 +36,43 @@ module ActiveModel klass.model_name.underscore.to_sym end - defaults << options.delete(:default) if options[:default] + defaults << options[:default] if options[:default] defaults << @human - options.reverse_merge! :scope => [@klass.i18n_scope, :models], :count => 1, :default => defaults + options = {:scope => [@klass.i18n_scope, :models], :count => 1, :default => defaults}.merge(options.except(:default)) I18n.translate(defaults.shift, options) end + + private + def _singularize(str) + ActiveSupport::Inflector.underscore(str).tr('/', '_') + end end # == Active Model Naming # # Creates a +model_name+ method on your object. - # + # # To implement, just extend ActiveModel::Naming in your object: - # + # # class BookCover # extend ActiveModel::Naming # 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 Active Model Lint test. So either extending the provided - # method below, or rolling your own is required.. + # method below, or rolling your own is required. module Naming # Returns an ActiveModel::Name object for module. It can be # used to retrieve all kinds of naming-related information. def model_name - @_model_name ||= ActiveModel::Name.new(self) + @_model_name ||= begin + namespace = self.parents.detect { |n| n.respond_to?(:_railtie) } + ActiveModel::Name.new(self, namespace) + end end # Returns the plural class name of a record or class. Examples: @@ -85,10 +99,38 @@ module ActiveModel plural(record_or_class) == singular(record_or_class) end + # Returns string to use while generating route names. It differs for + # namespaced models regarding whether it's inside isolated engine. + # + # For isolated engine: + # ActiveModel::Naming.route_key(Blog::Post) #=> posts + # + # For shared engine: + # ActiveModel::Naming.route_key(Blog::Post) #=> blog_posts + def self.route_key(record_or_class) + model_name_from_record_or_class(record_or_class).route_key + end + + # Returns string to use for params names. It differs for + # namespaced models regarding whether it's inside isolated engine. + # + # For isolated engine: + # ActiveModel::Naming.param_key(Blog::Post) #=> post + # + # For shared engine: + # ActiveModel::Naming.param_key(Blog::Post) #=> blog_post + def self.param_key(record_or_class) + model_name_from_record_or_class(record_or_class).param_key + end + private def self.model_name_from_record_or_class(record_or_class) - (record_or_class.is_a?(Class) ? record_or_class : record_or_class.class).model_name + (record_or_class.is_a?(Class) ? record_or_class : convert_to_model(record_or_class).class).model_name + end + + def self.convert_to_model(object) + object.respond_to?(:to_model) ? object.to_model : object end end - + end |