module Datagrid::Core
Simple example of using Datagrid
scope as the assets source to be queried from the database.
In most cases, the scope is a model class with some default ORM scopes, like ‘order` or `includes`:
The scope is also used to:
-
Choose an ORM driver (e.g., Mongoid, ActiveRecord, etc.).
-
Association preloading
-
Columns
Providing default order
You can set the scope at class level or instance level. Both having appropriate use cases
@example Defining a scope in a grid class
class ProjectsGrid < ApplicationGrid scope { Project.includes(:category) } end
@example Setting a scope at the instance level
grid = ProjectsGrid.new(grid_params) do |scope| scope.where(owner_id: current_user.id) end grid.assets # => SELECT * FROM projects WHERE projects.owner_id = ? AND [other filtering conditions]
@example Retrieving and redefining the scope
grid.scope # => SELECT * FROM projects WHERE projects.user_id = ? grid.redefined_scope? # => true # Reset scope to default class value grid.reset_scope grid.assets # => SELECT * FROM projects grid.redefined_scope? # => false # Overwriting the scope (ignoring previously defined) grid.scope { current_user.projects } grid.redefined_scope? # => true
Public Class Methods
Source
# File lib/datagrid/core.rb, line 48 def self.included(base) base.extend ClassMethods base.class_eval do class_attribute :scope_value class_attribute :datagrid_attributes, instance_writer: false, default: [] class_attribute :dynamic_block, instance_writer: false class_attribute :forbidden_attributes_protection, instance_writer: false, default: false class_attribute :default_filter_options, default: {} end end
@!visibility private
Source
# File lib/datagrid/core.rb, line 165 def initialize(attributes = nil, &block) super() self.attributes = attributes if attributes instance_eval(&dynamic_block) if dynamic_block return unless block_given? scope(&block) end
@param [Hash{String, Symbol => Object}] attributes a hash of attributes to initialize the object @yield [block] an optional block that is passed to the scope method for further customization @return [void] Initializes a new instance with optional attributes and an optional block.
Public Instance Methods
Source
# File lib/datagrid/core.rb, line 289 def ==(other) self.class == other.class && attributes == other.attributes && scope == other.scope end
Source
# File lib/datagrid/core.rb, line 196 def [](attribute) public_send(attribute) end
@param [String, Symbol] attribute attribute name @return [Object] Any datagrid attribute value
Source
Source
# File lib/datagrid/core.rb, line 217 def as_query attributes = self.attributes.clone attributes.each do |key, value| attributes.delete(key) if value.nil? end attributes end
@return [Hash{Symbol => Object}] serializable query arguments skipping all nil values @example
grid = ProductsGrid.new(category: 'dresses', available: true) grid.as_query # => {category: 'dresses', available: true}
Source
# File lib/datagrid/core.rb, line 209 def assets scope end
@return [Object] a scope relation (e.g ActiveRecord::Relation) with all applied filters
Source
# File lib/datagrid/core.rb, line 186 def attributes result = {} datagrid_attributes.each do |name| result[name] = self[name] end result end
@return [Hash{Symbol => Object}] grid attributes including filter values and ordering values @example
class UsersGrid < ApplicationGrid scope { User } filter(:first_name, :string) filter(:last_name, :string) end grid = UsersGrid.new(first_name: 'John', last_name: 'Smith') grid.attributes # => {first_name: 'John', last_name: 'Smith', order: nil, descending: nil}
Source
# File lib/datagrid/core.rb, line 277 def driver self.class.driver end
@!visibility private
Source
# File lib/datagrid/core.rb, line 282 def inspect attrs = attributes.map do |key, value| "#{key}: #{value.inspect}" end.join(", ") "#<#{self.class} #{attrs}>" end
@return [String] a datagrid attributes and their values in inspection form
Source
# File lib/datagrid/core.rb, line 261 def original_scope self.class.check_scope_defined! scope_value.call end
@!visibility private
Source
# File lib/datagrid/core.rb, line 230 def query_params(attributes = {}) { param_name.to_sym => as_query.merge(attributes) } end
@return [Hash{Symbol => Hash{Symbol => Object}}] query parameters to link this grid from a page @example
grid = ProductsGrid.new(category: 'dresses', available: true) Rails.application.routes.url_helpers.products_path(grid.query_params) # => "/products?products_grid[category]=dresses&products_grid[available]=true"
Source
# File lib/datagrid/core.rb, line 272 def redefined_scope? self.class.scope_value != scope_value end
@return [Boolean] true if the scope was redefined for this instance of grid object
Source
# File lib/datagrid/core.rb, line 296 def reset assets.reset end
@return [void] Resets loaded assets and column values cache
Source
# File lib/datagrid/core.rb, line 267 def reset_scope self.scope_value = self.class.scope_value end
@return [void] Resets current instance scope to default scope defined in a class
Source
# File lib/datagrid/core.rb, line 247 def scope(&block) if block_given? current_scope = scope self.scope_value = proc { Datagrid::Utils.apply_args(current_scope, &block) } self else scope = original_scope driver.to_scope(scope) end end
@return [void] redefines scope at instance level @example
class MyGrid scope { Article.order('created_at desc') } end grid = MyGrid.new grid.scope do |scope| scope.where(author_id: current_user.id) end grid.assets # => SELECT * FROM articles WHERE author_id = ? # ORDER BY created_at desc
Protected Instance Methods
Source
# File lib/datagrid/core.rb, line 302 def sanitize_for_mass_assignment(attributes) if forbidden_attributes_protection super elsif defined?(ActionController::Parameters) && attributes.is_a?(ActionController::Parameters) attributes.to_unsafe_h else attributes end end