Module: ActiveAdmin::ResourceController::DataAccess

Included in:
ActiveAdmin::ResourceController
Defined in:
lib/active_admin/resource_controller/data_access.rb

Overview

This module overrides most of the data access methods in Inherited Resources to provide Active Admin with it's data.

The module also deals with authorization and resource callbacks.

Constant Summary collapse

COLLECTION_APPLIES =
[
  :authorization_scope,
  :filtering,
  :scoping,
  :sorting,
  :includes,
  :pagination,
  :collection_decorator
].freeze

Instance Method Summary collapse

Instance Method Details

#apply_authorization_scope(collection) ⇒ ActiveRecord::Relation (protected)

Gives the authorization library a change to pre-scope the collection.

In the case of the CanCan adapter, it calls `#accessible_by` on the collection.

Parameters:

  • collection (ActiveRecord::Relation)

    The collection to scope

Returns:

  • (ActiveRecord::Relation)

    a scoped collection of query


199
200
201
202
# File 'lib/active_admin/resource_controller/data_access.rb', line 199

def apply_authorization_scope(collection)
  action_name = action_to_permission(params[:action])
  active_admin_authorization.scope_collection(collection, action_name)
end

#apply_decorations(resource) ⇒ ActiveRecord::Base (protected)

Returns resource.

Parameters:

  • resource (ActiveRecord::Base)

Returns:

  • (ActiveRecord::Base)

    resource


312
313
314
# File 'lib/active_admin/resource_controller/data_access.rb', line 312

def apply_decorations(resource)
  apply_decorator(resource)
end

#apply_filtering(chain) ⇒ Object (protected)

Applies any Ransack search methods to the currently scoped collection. Both `search` and `ransack` are provided, but we use `ransack` to prevent conflicts.


217
218
219
220
# File 'lib/active_admin/resource_controller/data_access.rb', line 217

def apply_filtering(chain)
  @search = chain.ransack(params[:q] || {})
  @search.result
end

#apply_includes(chain) ⇒ Object (protected)


232
233
234
235
236
237
238
# File 'lib/active_admin/resource_controller/data_access.rb', line 232

def apply_includes(chain)
  if active_admin_config.includes.any?
    chain.includes *active_admin_config.includes
  else
    chain
  end
end

#apply_pagination(chain) ⇒ Object (protected)


252
253
254
255
256
257
258
259
260
# File 'lib/active_admin/resource_controller/data_access.rb', line 252

def apply_pagination(chain)
  # skip pagination if CSV format was requested
  return chain if params["format"] == "csv"
  # skip pagination if already was paginated by scope
  return chain if chain.respond_to?(:total_pages)
  page = params[Kaminari.config.param_name]

  paginate(chain, page, per_page)
end

#apply_scoping(chain) ⇒ Object (protected)


222
223
224
225
226
227
228
229
230
# File 'lib/active_admin/resource_controller/data_access.rb', line 222

def apply_scoping(chain)
  @collection_before_scope = chain

  if current_scope
    scope_chain(current_scope, chain)
  else
    chain
  end
end

#apply_sorting(chain) ⇒ Object (protected)


204
205
206
207
208
209
210
211
212
213
# File 'lib/active_admin/resource_controller/data_access.rb', line 204

def apply_sorting(chain)
  params[:order] ||= active_admin_config.sort_order
  order_clause = active_admin_config.order_clause.new(active_admin_config, params[:order])

  if order_clause.valid?
    order_clause.apply(chain)
  else
    chain # just return the chain
  end
end

#assign_attributes(resource, attributes) ⇒ ActiveRecord::Base (protected)

Returns resource.

Parameters:

  • resource (ActiveRecord::Base)
  • attributes (Array<Hash])

    ttributes [Array<Hash]

Returns:

  • (ActiveRecord::Base)

    resource


299
300
301
302
303
304
305
306
307
# File 'lib/active_admin/resource_controller/data_access.rb', line 299

def assign_attributes(resource, attributes)
  if resource.respond_to?(:assign_attributes)
    resource.assign_attributes(*attributes)
  else
    resource.attributes = attributes[0]
  end

  resource
end

#build_new_resourceActiveRecord::Base (protected)

Builds a new resource. This method uses the method_for_build provided by Inherited Resources.

Returns:

  • (ActiveRecord::Base)

    An un-saved active record base object


131
132
133
134
135
136
# File 'lib/active_admin/resource_controller/data_access.rb', line 131

def build_new_resource
  apply_authorization_scope(scoped_collection).send(
    method_for_build,
    *resource_params.map { |params| params.slice(active_admin_config.resource_class.inheritance_column) }
  )
end

#build_resourceActiveRecord::Base (protected)

Builds, memoize and authorize a new instance of the resource. The actual work of building the new instance is delegated to the #build_new_resource method.

This method is used to instantiate and authorize new resources in the new and create controller actions.

Returns:

  • (ActiveRecord::Base)

    An un-saved active record base object


115
116
117
118
119
120
121
122
123
124
125
# File 'lib/active_admin/resource_controller/data_access.rb', line 115

def build_resource
  get_resource_ivar || begin
    resource = build_new_resource
    resource = apply_decorations(resource)
    resource = assign_attributes(resource, resource_params)
    run_build_callbacks resource
    authorize_resource! resource

    set_resource_ivar resource
  end
end

#collectionActiveRecord::Relation (protected)

Retrieve, memoize and authorize the current collection from the db. This method delegates the finding of the collection to #find_collection.

Once #collection has been called, the collection is available using either the @collection instance variable or an instance variable named after the resource that the collection is for. eg: Post => @post.

Returns:

  • (ActiveRecord::Relation)

    The collection for the index


43
44
45
46
47
48
49
# File 'lib/active_admin/resource_controller/data_access.rb', line 43

def collection
  get_collection_ivar || begin
    collection = find_collection
    authorize! Authorization::READ, active_admin_config.resource_class
    set_collection_ivar collection
  end
end

#collection_applies(options = {}) ⇒ Object (protected)


262
263
264
265
266
267
# File 'lib/active_admin/resource_controller/data_access.rb', line 262

def collection_applies(options = {})
  only = Array(options.fetch(:only, COLLECTION_APPLIES))
  except = Array(options.fetch(:except, []))

  COLLECTION_APPLIES & only - except
end

#collection_before_scopeObject (protected)


240
241
242
# File 'lib/active_admin/resource_controller/data_access.rb', line 240

def collection_before_scope
  @collection_before_scope
end

#configured_per_pageObject (protected)


291
292
293
# File 'lib/active_admin/resource_controller/data_access.rb', line 291

def configured_per_page
  Array(active_admin_config.per_page).first
end

#create_resource(object) ⇒ void (protected)

This method returns an undefined value.

Calls all the appropriate callbacks and then creates the new resource.

Parameters:

  • object (ActiveRecord::Base)

    The new resource to create


143
144
145
146
147
# File 'lib/active_admin/resource_controller/data_access.rb', line 143

def create_resource(object)
  run_create_callbacks object do
    save_resource(object)
  end
end

#current_scopeObject (protected)


244
245
246
247
248
249
250
# File 'lib/active_admin/resource_controller/data_access.rb', line 244

def current_scope
  @current_scope ||= if params[:scope]
                       active_admin_config.get_scope_by_id(params[:scope])
                     else
                       active_admin_config.default_scope(self)
                     end
end

#destroy_resource(object) ⇒ void (protected)

This method returns an undefined value.

Destroys an object from the database and calls appropriate callbacks.


181
182
183
184
185
# File 'lib/active_admin/resource_controller/data_access.rb', line 181

def destroy_resource(object)
  run_destroy_callbacks object do
    object.destroy
  end
end

#dynamic_per_pageObject (protected)


287
288
289
# File 'lib/active_admin/resource_controller/data_access.rb', line 287

def dynamic_per_page
  params[:per_page] || @per_page
end

#find_collection(options = {}) ⇒ ActiveRecord::Relation (protected)

Does the actual work of retrieving the current collection from the db. This is a great method to override if you would like to perform some additional db # work before your controller returns and authorizes the collection.

Returns:

  • (ActiveRecord::Relation)

    The collection for the index


57
58
59
60
61
62
63
# File 'lib/active_admin/resource_controller/data_access.rb', line 57

def find_collection(options = {})
  collection = scoped_collection
  collection_applies(options).each do |applyer|
    collection = send("apply_#{applyer}", collection)
  end
  collection
end

#find_resourceActiveRecord::Base (protected)

Does the actual work of finding a resource in the database. This method uses the finder method as defined in InheritedResources.

Returns:

  • (ActiveRecord::Base)

    An active record object.


103
104
105
# File 'lib/active_admin/resource_controller/data_access.rb', line 103

def find_resource
  scoped_collection.send method_for_find, params[:id]
end

#in_paginated_batches(&block) ⇒ Object (protected)


269
270
271
272
273
274
275
276
277
# File 'lib/active_admin/resource_controller/data_access.rb', line 269

def in_paginated_batches(&block)
  ActiveRecord::Base.uncached do
    (1..paginated_collection.total_pages).each do |page|
      paginated_collection(page).each do |resource|
        yield apply_decorator(resource)
      end
    end
  end
end

#per_pageObject (protected)


279
280
281
282
283
284
285
# File 'lib/active_admin/resource_controller/data_access.rb', line 279

def per_page
  if active_admin_config.paginate
    dynamic_per_page || configured_per_page
  else
    active_admin_config.max_per_page
  end
end

#resourceActiveRecord::Base (protected)

Retrieve, memoize and authorize a resource based on params. The actual work of finding the resource is done in #find_resource.

This method is used on all the member actions:

* show
* edit
* update
* destroy

Returns:

  • (ActiveRecord::Base)

    An active record object


89
90
91
92
93
94
95
96
97
# File 'lib/active_admin/resource_controller/data_access.rb', line 89

def resource
  get_resource_ivar || begin
    resource = find_resource
    resource = apply_decorations(resource)
    authorize_resource! resource

    set_resource_ivar resource
  end
end

#save_resource(object) ⇒ void (protected)

This method returns an undefined value.

Calls all the appropriate callbacks and then saves the new resource.

Parameters:

  • object (ActiveRecord::Base)

    The new resource to save


154
155
156
157
158
# File 'lib/active_admin/resource_controller/data_access.rb', line 154

def save_resource(object)
  run_save_callbacks object do
    object.save
  end
end

#scoped_collectionObject (protected)

Override this method in your controllers to modify the start point of our searches and index.

This method should return an ActiveRecord::Relation object so that the searching and filtering can be applied on top

Note, unless you are doing something special, you should use the scope_to method from the Scoping module instead of overriding this method.


74
75
76
# File 'lib/active_admin/resource_controller/data_access.rb', line 74

def scoped_collection
  end_of_association_chain
end

#smart_resource_urlString (protected)

Returns:

  • (String)

317
318
319
320
321
322
323
# File 'lib/active_admin/resource_controller/data_access.rb', line 317

def smart_resource_url
  if create_another?
    new_resource_url(create_another: params[:create_another])
  else
    super
  end
end

#update_resource(object, attributes) ⇒ void (protected)

This method returns an undefined value.

Update an object with the given attributes. Also calls the appropriate callbacks for update action.

Parameters:

  • object (ActiveRecord::Base)

    The instance to update

  • attributes (Array)

    An array with the attributes in the first position and the Active Record “role” in the second. The role may be set to nil.


170
171
172
173
174
175
176
# File 'lib/active_admin/resource_controller/data_access.rb', line 170

def update_resource(object, attributes)
  object = assign_attributes(object, attributes)

  run_update_callbacks object do
    save_resource(object)
  end
end