module InheritedResources::ClassMethods

Protected Instance Methods

actions(*actions_to_keep) click to toggle source

Defines which actions will be inherited from the inherited controller. Syntax is borrowed from resource_controller.

actions :index, :show, :edit
actions :all, :except => :index
# File lib/inherited_resources/class_methods.rb, line 76
def actions(*actions_to_keep)
  raise ArgumentError, 'Wrong number of arguments. You have to provide which actions you want to keep.' if actions_to_keep.empty?

  options = actions_to_keep.extract_options!
  actions_to_remove = Array(options[:except])
  actions_to_remove += ACTIONS - actions_to_keep.map { |a| a.to_sym } unless actions_to_keep.first == :all
  actions_to_remove.map! { |a| a.to_sym }.uniq!
  (instance_methods.map { |m| m.to_sym } & actions_to_remove).each do |action|
    undef_method action, "#{action}!"
  end
end
belongs_to(*symbols, &block) click to toggle source

Defines that this controller belongs to another resource.

belongs_to :projects

Options

  • :parent_class - Allows you to specify what is the parent class.

    belongs_to :project, :parent_class => AdminProject
    
  • :class_name - Also allows you to specify the parent class, but you should

    give a string. Added for ActiveRecord belongs to compatibility.
  • :instance_name - The instance variable name. By default is the name of the association.

    belongs_to :project, :instance_name => :my_project
    
  • :finder - Specifies which method should be called to instantiate the parent.

    belongs_to :project, :finder => :find_by_title!
    

    This will make your projects be instantiated as:

    Project.find_by_title!(params[:project_id])
    

    Instead of:

    Project.find(params[:project_id])
    
  • :param - Allows you to specify params key to retrieve the id.

    Default is :association_id, which in this case is :project_id.
  • :route_name - Allows you to specify what is the route name in your url

    helper. By default is association name.
  • :collection_name - Tell how to retrieve the next collection. Let’s

                             suppose you have Tasks which belongs to Projects
                             which belongs to companies. This will do somewhere
                             down the road:
    
    @company.projects

    But if you want to retrieve instead:

    @company.admin_projects
    

    You supply the collection name.

  • :polymorphic - Tell the association is polymorphic.

  • :singleton - Tell it’s a singleton association.

  • :optional - Tell the association is optional (it’s a special

    type of polymorphic association)
# File lib/inherited_resources/class_methods.rb, line 143
def belongs_to(*symbols, &block)
  options = symbols.extract_options!

  options.symbolize_keys!
  options.assert_valid_keys(:class_name, :parent_class, :instance_name, :param,
                            :finder, :route_name, :collection_name, :singleton,
                            :polymorphic, :optional, :shallow)

  optional    = options.delete(:optional)
  shallow     = options.delete(:shallow)
  polymorphic = options.delete(:polymorphic)
  finder      = options.delete(:finder)

  if self.parents_symbols.empty?
    include BelongsToHelpers
    helper_method :parent, :parent?
  end

  acts_as_polymorphic! if polymorphic || optional
  acts_as_shallow!     if shallow

  raise ArgumentError, 'You have to give me at least one association name.' if symbols.empty?
  raise ArgumentError, "You cannot define multiple associations with options: #{options.keys.inspect} to belongs to." unless symbols.size == 1 || options.empty?

  symbols.each do |symbol|
    symbol = symbol.to_sym

    if polymorphic || optional
      self.parents_symbols << :polymorphic unless self.parents_symbols.include?(:polymorphic)
      self.resources_configuration[:polymorphic][:symbols]   << symbol
      self.resources_configuration[:polymorphic][:optional] ||= optional
    else
      self.parents_symbols << symbol
    end

    self.resources_configuration[:self][:shallow] = true if shallow

    config = self.resources_configuration[symbol] = {}

    class_name = ''
    config[:parent_class] = options.delete(:parent_class) ||
      begin
        class_name = if options[:class_name]
          options.delete(:class_name)
        else
          namespace = self.name.deconstantize
          model_name = symbol.to_s.pluralize.classify

          klass = model_name
          while namespace != ''
            new_klass = "#{namespace}::#{model_name}"
            if new_klass.safe_constantize
              klass = new_klass
              break
            else
              namespace = namespace.deconstantize
            end
          end

          klass = model_name if klass.start_with?('::')

          klass
        end
        class_name.constantize
      rescue NameError => e
        raise unless e.message.include?(class_name)
        nil
      end

    config[:singleton]       = options.delete(:singleton) || false
    config[:collection_name] = options.delete(:collection_name) || symbol.to_s.pluralize.to_sym
    config[:instance_name]   = options.delete(:instance_name) || symbol
    config[:param]           = options.delete(:param) || :"#{symbol}_id"
    config[:route_name]      = options.delete(:route_name) || symbol
    config[:finder]          = finder || :find
  end

  if block
    class_eval(&block)
  else
    create_resources_url_helpers!
  end
end
Also aliased as: nested_belongs_to
custom_actions(options) click to toggle source

Defines custom restful actions by resource or collection basis.

custom_actions :resource => [:delete, :transit], :collection => :search

Options

  • :resource - Allows you to specify resource actions.

    custom_actions :resource => :delete
                        This macro creates 'delete' method in controller and defines
                        delete_resource_{path,url} helpers. The body of generated 'delete'
                        method is same as 'show' method. So you can override it if need
  • :collection - Allows you to specify collection actions.

    custom_actions :collection => :search
                        This macro creates 'search' method in controller and defines
                        search_resources_{path,url} helpers. The body of generated 'search'
                        method is same as 'index' method. So you can override it if need
# File lib/inherited_resources/class_methods.rb, line 270
def custom_actions(options)
  self.resources_configuration[:self][:custom_actions] = options
  options.each do | resource_or_collection, actions |
    [*actions].each do | action |
      create_custom_action(resource_or_collection, action)
    end
  end
  create_resources_url_helpers!
  [*options[:resource]].each do | action |
    helper_method "#{action}_resource_path", "#{action}_resource_url"
  end
  [*options[:collection]].each do | action |
    helper_method "#{action}_resources_path", "#{action}_resources_url"
  end
end
defaults(options) click to toggle source

Used to overwrite the default assumptions InheritedResources do. Whenever this method is called, it should be on the top of your controller, since almost other methods depends on the values given to <>defaults.

Options

  • :resource_class - The resource class which by default is guessed

    by the controller name. Defaults to Project in
    ProjectsController.
  • :collection_name - The name of the collection instance variable which

    is set on the index action. Defaults to :projects in
    ProjectsController.
  • :instance_name - The name of the singular instance variable which

    is set on all actions besides index action. Defaults to
    :project in ProjectsController.
  • :route_collection_name - The name of the collection route. Defaults to :collection_name.

  • :route_instance_name - The name of the singular route. Defaults to :instance_name.

  • :route_prefix - The route prefix which is automatically set in namespaced

    controllers. Default to :admin on Admin::ProjectsController.
  • :singleton - Tells if this controller is singleton or not.

  • :finder - Specifies which method should be called to instantiate the resource.

    defaults :finder => :find_by_slug
    
# File lib/inherited_resources/class_methods.rb, line 39
def defaults(options)
  raise ArgumentError, 'Class method :defaults expects a hash of options.' unless options.is_a? Hash

  options.symbolize_keys!
  options.assert_valid_keys(:resource_class, :collection_name, :instance_name,
                            :class_name, :route_prefix, :route_collection_name,
                            :route_instance_name, :singleton, :finder)

  self.resource_class = options[:resource_class] if options.key?(:resource_class)
  self.resource_class = options[:class_name].constantize if options.key?(:class_name)

  acts_as_singleton! if options.delete(:singleton)

  config = self.resources_configuration[:self]

  if options.key?(:resource_class) or options.key?(:class_name)
    config[:request_name] = begin
      request_name = self.resource_class
      request_name = request_name.model_name.param_key if request_name.respond_to?(:model_name)
      request_name.to_s.underscore.tr('/', '_')
    end
    options.delete(:resource_class) and options.delete(:class_name)
  end

  options.each do |key, value|
    config[key] = value&.to_sym
  end

  create_resources_url_helpers!
end
nested_belongs_to(*symbols, &block)
Alias for: belongs_to
optional_belongs_to(*symbols, &block) click to toggle source

A quick method to declare optional belongs to.

# File lib/inherited_resources/class_methods.rb, line 246
def optional_belongs_to(*symbols, &block)
  options = symbols.extract_options!
  options[:optional] = true
  belongs_to(*symbols, options, &block)
end
polymorphic_belongs_to(*symbols, &block) click to toggle source

A quick method to declare polymorphic belongs to.

# File lib/inherited_resources/class_methods.rb, line 230
def polymorphic_belongs_to(*symbols, &block)
  options = symbols.extract_options!
  options[:polymorphic] = true
  belongs_to(*symbols, options, &block)
end
singleton_belongs_to(*symbols, &block) click to toggle source

A quick method to declare singleton belongs to.

# File lib/inherited_resources/class_methods.rb, line 238
def singleton_belongs_to(*symbols, &block)
  options = symbols.extract_options!
  options[:singleton] = true
  belongs_to(*symbols, options, &block)
end
with_role(role) click to toggle source

Defines the role to use when creating or updating resource. Makes sense when using rails 3.1 mass assignment conventions

# File lib/inherited_resources/class_methods.rb, line 288
def with_role(role)
  self.resources_configuration[:self][:role] = role.try(:to_sym)
end
without_protection(flag) click to toggle source
# File lib/inherited_resources/class_methods.rb, line 292
def without_protection(flag)
  self.resources_configuration[:self][:without_protection] = flag
end

Private Instance Methods

create_custom_action(resource_or_collection, action) click to toggle source
# File lib/inherited_resources/class_methods.rb, line 397
      def create_custom_action(resource_or_collection, action)
        class_eval <<-CUSTOM_ACTION, __FILE__, __LINE__
          def #{action}(options={}, &block)
            respond_with(*with_chain(#{resource_or_collection}), options, &block)
          end
          alias :#{action}! :#{action}
          protected :#{action}!
        CUSTOM_ACTION
      end