module InheritedResources::ClassMethods
def actions(*actions_to_keep)
actions :all, :except => :index
actions :index, :show, :edit
Syntax is borrowed from resource_controller.
Defines wich actions to keep from the inherited controller.
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
def acts_as_polymorphic! #:nodoc:
def acts_as_polymorphic! #:nodoc: unless self.parents_symbols.include?(:polymorphic) include PolymorphicHelpers helper_method :parent, :parent_type, :parent_class, :parent? end end
def acts_as_singleton! #:nodoc:
def acts_as_singleton! #:nodoc: unless self.resources_configuration[:self][:singleton] self.resources_configuration[:self][:singleton] = true include SingletonHelpers actions :all, :except => :index end end
def belongs_to(*symbols, &block)
type of polymorphic association)
* :optional - Tell the association is optional (it's a special
* :singleton - Tell it's a singleton association.
* :polymorphic - Tell the association is polymorphic.
You supply the collection name.
@company.admin_projects
But if you want to retrieve instead:
@company.projects
down the road:
which belongs to companies. This will do somewhere
suppose you have Tasks which belongs to Projects
* :collection_name - Tell how to retrieve the next collection. Let's
helper. By default is association name.
* :route_name - Allows you to specify what is the route name in your url
Default is :association_id, which in this case is :project_id.
* :param - Allows you to specify params key to retrieve the id.
Project.find(params[:project_id])
Instead of:
Project.find_by_title!(params[:project_id])
This will make your projects be instantiated as:
belongs_to :project, :finder => :find_by_title!
* :finder - Specifies which method should be called to instantiate the parent.
belongs_to :project, :instance_name => :my_project
* :instance_name - The instance variable name. By default is the name of the association.
give a string. Added for ActiveRecord belongs to compatibility.
* :class_name - Also allows you to specify the parent class, but you should
belongs_to :project, :parent_class => AdminProject
* :parent_class - Allows you to specify what is the parent class.
== Options
belongs_to :projects
Defines that this controller belongs to another resource.
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) optional = options.delete(:optional) singleton = options.delete(:singleton) polymorphic = options.delete(:polymorphic) finder = options.delete(:finder) include BelongsToHelpers if self.parents_symbols.empty? acts_as_singleton! if singleton acts_as_polymorphic! if polymorphic || optional 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 config = self.resources_configuration[symbol] = {} config[:parent_class] = options.delete(:parent_class) || begin class_name = (options.delete(:class_name) || symbol).to_s.pluralize.classify class_name.constantize rescue NameError => e raise unless e.message.include?(class_name) nil end 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_given? class_eval(&block) else create_resources_url_helpers! end end
def defaults(options)
* :singleton - Tells if this controller is singleton or not.
controllers. Default to :admin on Admin::ProjectsController.
* :route_prefix - The route prefix which is automically set in namespaced
* :route_instance_name - The name of the singular route. Defaults to :instance_name.
* :route_collection_name - The name of the collection route. Defaults to :collection_name.
:project in ProjectsController.
is set on all actions besides index action. Defaults to
* :instance_name - The name of the singular instance variable which
ProjectsController.
is set on the index action. Defaults to :projects in
* :collection_name - The name of the collection instance variable which
ProjectsController.
by the controller name. Defaults to Project in
* :resource_class - The resource class which by default is guessed
== Options
almost other methods depends on the values given to <>defaults.
this method is called, it should be on the top of your controller, since
Used to overwrite the default assumptions InheritedResources do. Whenever
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) self.resource_class = options.delete(:resource_class) if options.key?(:resource_class) self.resource_class = options.delete(:class_name).constantize if options.key?(:class_name) acts_as_singleton! if options.delete(:singleton) config = self.resources_configuration[:self] config[:route_prefix] = options.delete(:route_prefix) if options.key?(:route_prefix) options.each do |key, value| config[key] = value.to_sym end create_resources_url_helpers! end
def inherited(base) #:nodoc:
Hook called on inheritance.
def inherited(base) #:nodoc: super(base) base.send :initialize_resources_class_accessors! base.send :create_resources_url_helpers! end
def initialize_resources_class_accessors! #:nodoc:
Initialize resources class accessors and set their default values.
def initialize_resources_class_accessors! #:nodoc: # Initialize resource class self.resource_class = begin class_name = self.controller_name.classify class_name.constantize rescue NameError => e raise unless e.message.include?(class_name) nil end # Initialize resources configuration hash self.resources_configuration ||= {} config = self.resources_configuration[:self] = {} config[:collection_name] = self.controller_name.to_sym config[:instance_name] = self.controller_name.singularize.to_sym config[:route_collection_name] = config[:collection_name] config[:route_instance_name] = config[:instance_name] # Deal with namespaced controllers namespaces = self.controller_path.split('/')[0..-2] config[:route_prefix] = namespaces.join('_') unless namespaces.empty? # Initialize polymorphic, singleton, scopes and belongs_to parameters self.parents_symbols ||= [] self.resources_configuration[:polymorphic] ||= { :symbols => [], :optional => false } end
def optional_belongs_to(*symbols, &block)
A quick method to declare optional belongs to.
def optional_belongs_to(*symbols, &block) options = symbols.extract_options! options.merge!(:optional => true) belongs_to(*symbols << options, &block) end
def polymorphic_belongs_to(*symbols, &block)
A quick method to declare polymorphic belongs to.
def polymorphic_belongs_to(*symbols, &block) options = symbols.extract_options! options.merge!(:polymorphic => true) belongs_to(*symbols << options, &block) end
def singleton_belongs_to(*symbols, &block)
A quick method to declare singleton belongs to.
def singleton_belongs_to(*symbols, &block) options = symbols.extract_options! options.merge!(:singleton => true) belongs_to(*symbols << options, &block) end