Module: Heimdallr::LegacyResource Deprecated
- Extended by:
- ActiveSupport::Concern
- Defined in:
- lib/heimdallr/legacy_resource.rb
Overview
Will be removed ASAP. Please don’t use it in favour of github.com/roundlake/heimdallr-resource/
Heimdallr LegacyResource is a boilerplate for simple creation of REST endpoints, most of which are quite similar and thus may share a lot of code.
The minimal controller possible would be:
class MiceController < ApplicationController
include Heimdallr::Resource
# Class Mouse must include Heimdallr::Model.
resource_for :mouse
end
Resource is built with Convention over Configuration principle in mind; that is, instead of providing complex configuration syntax, Resource consists of a lot of small, easy to override methods. If some kind of default behavior is undesirable, then one can just override the relative method in the particular controller or, say, define a module if the changes are to be shared between several controllers. You are encouraged to explore the source of this class.
Resource allows to perform efficient operations on collections of objects. The #create, #update and #destroy actions accept both a single object/ID or an array of objects/IDs. The cardinal _modus
Resource expects a method named security_context
to be defined either in the controller itself or, more conveniently, in any of its ancestors, likely ApplicationController
. This method can often be aliased to current_user
.
Resource only works with ActiveRecord.
See also Resource::ClassMethods.
Defined Under Namespace
Modules: ClassMethods
Actions collapse
-
#create ⇒ Object
POST /resources.
-
#destroy ⇒ Object
DELETE /resources/1,2.
-
#edit ⇒ Object
GET /resources/1/edit.
-
#index ⇒ Object
GET /resources.
-
#new ⇒ Object
GET /resources/new.
-
#show ⇒ Object
GET /resource/1.
-
#update ⇒ Object
PUT /resources/1,2.
Configuration collapse
-
#load_all_resources ⇒ Object
protected
Loads all resources in the current scope to @resources.
-
#load_referenced_resources ⇒ Object
protected
Loads several resources from the current scope, referenced by
params[:id]
with a comma-separated string like “1,2,3”, to @resources. -
#model ⇒ Class
protected
Return the associated model class.
- #render_data(options = {}) ⇒ Object protected
-
#restricted_model ⇒ Object
protected
Return the scoped and restricted model.
-
#scoped_model ⇒ Object
protected
Return the appropriately scoped model.
-
#with_objects_from_params(options = {}) {|attributes, index| ... } ⇒ Object
protected
Fetch one or several objects passed in
params
and yield them to a block, wrapping everything in a transaction.
Instance Method Details
#create ⇒ Object
POST /resources
This action creates one or more records from the passed parameters. It can accept both arrays of attribute hashes and single attribute hashes.
After the creation, it calls #render_data.
See also #load_referenced_resources and #with_objects_from_params.
72 73 74 75 76 77 78 |
# File 'lib/heimdallr/legacy_resource.rb', line 72 def create with_objects_from_params(replace: true) do |object, attributes| restricted_model.create(attributes) end render_data verify: true end |
#destroy ⇒ Object
DELETE /resources/1,2
This action destroys one or more records. It expects resource IDs to be passed comma-separated in params[:id]
.
See also #load_referenced_resources.
114 115 116 117 118 119 120 |
# File 'lib/heimdallr/legacy_resource.rb', line 114 def destroy with_objects_from_params do |object, attributes| object.destroy end render :json => {}, :status => :ok end |
#edit ⇒ Object
GET /resources/1/edit
This action renders a JSON representation of fields whitelisted for updating. See also #new.
84 85 86 87 88 |
# File 'lib/heimdallr/legacy_resource.rb', line 84 def edit render :json => { :fields => model.restrictions(security_context).allowed_fields[:update] } end |
#index ⇒ Object
GET /resources
This action does nothing by itself, but it has a load_all_resources
filter attached.
40 41 42 |
# File 'lib/heimdallr/legacy_resource.rb', line 40 def index render_data end |
#load_all_resources ⇒ Object (protected)
Loads all resources in the current scope to @resources.
Is automatically applied to #index.
175 176 177 178 |
# File 'lib/heimdallr/legacy_resource.rb', line 175 def load_all_resources @multiple_resources = true @resources = restricted_model end |
#load_referenced_resources ⇒ Object (protected)
184 185 186 187 188 189 190 191 192 |
# File 'lib/heimdallr/legacy_resource.rb', line 184 def load_referenced_resources if params[:id][0] == '*' @multiple_resources = true @resources = restricted_model.find(params[:id][1..-1].split(',')) else @multiple_resources = false @resource = restricted_model.find(params[:id]) end end |
#model ⇒ Class (protected)
Return the associated model class.
128 129 130 |
# File 'lib/heimdallr/legacy_resource.rb', line 128 def model self.class.model end |
#new ⇒ Object
GET /resources/new
This action renders a JSON representation of fields whitelisted for creation. It does not include any fixtures or validations.
58 59 60 61 62 |
# File 'lib/heimdallr/legacy_resource.rb', line 58 def new render :json => { :fields => model.restrictions(security_context).allowed_fields[:create] } end |
#render_data(options = {}) ⇒ Object (protected)
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'lib/heimdallr/legacy_resource.rb', line 195 def render_data(={}) if @multiple_resources if [:verify] && @resources.any?(&:invalid?) render :json => { errors: @resources.map(&:errors) }, :status => :unprocessable_entity else render :action => :index end else if [:verify] && @resource.invalid? render :json => @resource.errors, :status => :unprocessable_entity else render :action => :show end end end |
#restricted_model ⇒ Object (protected)
Return the scoped and restricted model. By default this method restricts the result of #scoped_model with security_context
, which is expected to be defined on this class or its ancestors.
168 169 170 |
# File 'lib/heimdallr/legacy_resource.rb', line 168 def restricted_model scoped_model.restrict(security_context, implicit: true) end |
#scoped_model ⇒ Object (protected)
Return the appropriately scoped model. By default this method delegates to self.model.scoped
; you may override it for nested resources so that it would only return the nested set.
For example, this code would not allow user to perform any actions with a transaction from a wrong account, raising RecordNotFound instead:
# transactions_controller.rb
class TransactionsController < ApplicationController
include Heimdallr::Resource
resource_for :transactions
protected
def scoped_model
Account.find(params[:account_id]).transactions
end
end
# routes.rb
Foo::Application.routes.draw do
resources :accounts do
resources :transactions
end
end
161 162 163 |
# File 'lib/heimdallr/legacy_resource.rb', line 161 def scoped_model self.model.scoped end |
#show ⇒ Object
GET /resource/1
This action does nothing by itself, but it has a load_one_resource
filter attached.
47 48 49 |
# File 'lib/heimdallr/legacy_resource.rb', line 47 def show render_data end |
#update ⇒ Object
PUT /resources/1,2
This action updates one or more records from the passed parameters. It expects resource IDs to be passed comma-separated in params[:id]
, and expects them to be in the order corresponding to the order of actual attribute hashes.
After the updating, it calls #render_data.
See also #load_referenced_resources and #with_objects_from_params.
100 101 102 103 104 105 106 |
# File 'lib/heimdallr/legacy_resource.rb', line 100 def update with_objects_from_params do |object, attributes| object.update_attributes attributes end render_data verify: true end |
#with_objects_from_params(options = {}) {|attributes, index| ... } ⇒ Object (protected)
Fetch one or several objects passed in params
and yield them to a block, wrapping everything in a transaction.
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 |
# File 'lib/heimdallr/legacy_resource.rb', line 217 def with_objects_from_params(={}) model.transaction do if @multiple_resources begin name = model.name.underscore.pluralize if params[name].is_a? Hash enumerator = params[name].keys.each else enumerator = params[name].each_index end result = enumerator.map do |index| yield(@resources[index.to_i], params[name][index]) end ensure @resources = result if [:replace] end else begin result = yield(@resource, params[model.name.underscore]) ensure @resource = result if [:replace] end end end end |