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 ArgumentErrors.
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 |