Module: ResponderController::ClassMethods
- Defined in:
- lib/responder_controller/class_methods.rb
Overview
Configure how the controller finds and serves models of what flavor.
Instance Attribute Summary collapse
-
#scopes ⇒ Object
readonly
The array of declared class-level scopes, as symbols or procs.
Instance Method Summary collapse
-
#children_of(parent_model_class_name) ⇒ Object
Declare a (non-singleton) parent resource class.
-
#model_class ⇒ Object
The served model class, identified by #model_class_name.
-
#model_class_name ⇒ Object
The underscored, fully-qualified name of the served model class.
-
#responds_within(*args, &block) ⇒ Object
Declare leading arguments (“responder context”) for
#respond_with
. -
#scope(*args, &block) ⇒ Object
Declare a class-level scope for model collections.
-
#serves_model(model_class_name) ⇒ Object
Declare the underscored, fully-qualified name of the served model class.
-
#serves_scopes(options = nil) ⇒ Object
Declare what active record scopes to allow or forbid to requests.
Instance Attribute Details
#scopes ⇒ Object (readonly)
The array of declared class-level scopes, as symbols or procs.
110 111 112 |
# File 'lib/responder_controller/class_methods.rb', line 110 def scopes @scopes end |
Instance Method Details
#children_of(parent_model_class_name) ⇒ Object
Declare a (non-singleton) parent resource class.
children_of 'accounts/user'
implies a scope and some responder context. The scope performs an ActiveRecord where :user_id => params[:user_id]
. The responder context is a call to #responds_within
declaring the parent model’s modules along with the parent itself, found with Accounts::User.find(params[:user_id])
.
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/responder_controller/class_methods.rb', line 120 def children_of(parent_model_class_name) parent_model_class_name = parent_model_class_name.to_s.underscore parent_name_parts = parent_model_class_name.split('/') parent_modules = parent_name_parts[0...-1].collect(&:to_sym) parent_id = "#{parent_name_parts.last}_id".to_sym # TODO: primary key scope do |query| query.where parent_id => params[parent_id] end responds_within do parent = parent_model_class_name.camelize.constantize. find params[parent_id] parent_modules + [parent] end end |
#model_class ⇒ Object
The served model class, identified by #model_class_name.
84 85 86 |
# File 'lib/responder_controller/class_methods.rb', line 84 def model_class model_class_name.camelize.constantize end |
#model_class_name ⇒ Object
The underscored, fully-qualified name of the served model class.
By default, it is the underscored controller class name, without _controller
.
8 9 10 11 |
# File 'lib/responder_controller/class_methods.rb', line 8 def model_class_name @model_class_name || \ name.underscore.gsub(/_controller$/, '').singularize end |
#responds_within(*args, &block) ⇒ Object
Declare leading arguments (“responder context”) for #respond_with
.
respond_with
creates urls from models. To avoid strongly coupling models to a url structure, it can take any number of leading parameters a la #polymorphic_url
. #responds_within
declares these leading parameters, to be used on each respond_with
call.
It takes either a varargs or a block, but not both. In InstanceMethods#respond_with_contextual, the blocks are called with #instance_exec
, taking the model (or models) as a parameter. They should return an array.
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/responder_controller/class_methods.rb', line 66 def responds_within(*args, &block) if block and args.any? raise ArgumentError.new( "responds_within can take arguments or a block, but not both") elsif block or args.any? @responds_within ||= [] if not args.empty? @responds_within.concat args else @responds_within << block end end @responds_within || \ model_class_name.split('/')[0...-1].collect { |m| m.to_sym } end |
#scope(*args, &block) ⇒ Object
Declare a class-level scope for model collections.
The model class is expected to respond to all
, returning an Enumerable of models. Declared scopes are applied to (and replace) this collection, suitable for active record scopes.
It takes one of a string, symbol or block. Symbols and strings are called as methods on the collection without arguments. Blocks are called with #instance_exec
taking the current, accumulated query and returning the new, scoped one.
98 99 100 101 102 103 104 105 106 107 |
# File 'lib/responder_controller/class_methods.rb', line 98 def scope(*args, &block) scope = args.first || block scope = scope.to_sym if String === scope unless scope.is_a? Symbol or scope.is_a? Proc raise ArgumentError.new "Scope must be a string, symbol or block" end (@scopes ||= []) << scope end |
#serves_model(model_class_name) ⇒ Object
Declare the underscored, fully-qualified name of the served model class.
Modules are declared with separating slashes, such as in admin/setting
. Strings or symbols are accepted, but other values (including actual classes) will raise ArgumentError
s.
18 19 20 21 22 23 24 |
# File 'lib/responder_controller/class_methods.rb', line 18 def serves_model(model_class_name) unless model_class_name.is_a? String or model_class_name.is_a? Symbol raise ArgumentError.new "Model must be a string or symbol" end @model_class_name = model_class_name.to_s end |
#serves_scopes(options = nil) ⇒ Object
Declare what active record scopes to allow or forbid to requests.
.serves_scopes follows the regular :only/:except form: white-listed scopes are passed by name as :only => [:allowed, :scopes]
or :only => :just_one
. Similarly, black-listed ones are passed under :except
.
If a white-list is passed, all other requested scopes (i.e. scopes named by query parameters) will be denied, raising ForbiddenScope
. If a black-list is passed, only they will raise the exception.
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/responder_controller/class_methods.rb', line 36 def serves_scopes( = nil) @serves_scopes ||= {} if raise TypeError unless .is_a? Hash new_keys = @serves_scopes.keys | .keys unless new_keys == [:only] or new_keys == [:except] raise ArgumentError.new( "serves_scopes takes exactly one of :only and :except") end @serves_scopes[.keys.first] ||= [] @serves_scopes[.keys.first].concat [*.values.first] end @serves_scopes end |