class AzaharaSchema::Schema

Attributes

association[RW]
default_scope[RW]
enabled_outputs[RW]
limit[RW]
model[RW]
offset[RW]
parent_schema[RW]
search_query[RW]

Public Class Methods

attribute(model, name, attr_type=nil) click to toggle source
# File lib/azahara_schema/schema.rb, line 44
def self.attribute(model, name, attr_type=nil)
  attr_type ||= attribute_type(model, name)
  Attribute.new(model, name, attr_type)
end
attribute_for_column(model, col, attr_type=nil) click to toggle source
# File lib/azahara_schema/schema.rb, line 49
def self.attribute_for_column(model, col, attr_type=nil)
  attribute(model, col.name, attr_type || attribute_type(model, col.name, col) )
end
attribute_type(model, name, col=nil) click to toggle source
# File lib/azahara_schema/schema.rb, line 35
def self.attribute_type(model, name, col=nil)
  col ||= model.columns_hash[name.to_s]
  if model.defined_enums[col.name]
    'list'
  else
    col && col.type
  end
end
enabled_filters(*filter_names) click to toggle source
# File lib/azahara_schema/schema.rb, line 53
def self.enabled_filters(*filter_names)
  @enabled_filters = filter_names if filter_names.any?
  @enabled_filters ||= []
end
filter_operators(filter, operators) click to toggle source
# File lib/azahara_schema/schema.rb, line 62
def self.filter_operators(filter, operators)
  operators_for_filters[filter] = operators
end
new(model, **attributes) click to toggle source
# File lib/azahara_schema/schema.rb, line 70
def initialize(model, **attributes)
  @model = model
  @association = attributes[:association]
  @parent_schema = attributes[:parent_schema]
  @column_names = attributes[:columns]
  @enabled_outputs = attributes[:outputs] || default_outputs
  @nested_relations_depth = attributes[:relations_depth]
end
operators_for_filters() click to toggle source
# File lib/azahara_schema/schema.rb, line 58
def self.operators_for_filters
  @operators_for_filters ||= {}
end
schema_class_for(klass) click to toggle source
# File lib/azahara_schema/schema.rb, line 6
def self.schema_class_for(klass)
  klasses = [klass]
  while klass != klass.base_class
    klass = klass.superclass
    klasses << klass
  end
  klasses.each do |kls|
    schema_klass = "#{kls.name}Schema".safe_constantize
    return schema_klass if schema_klass
  end
  AzaharaSchema::Schema
end
schema_for(klass, *attributes) click to toggle source
# File lib/azahara_schema/schema.rb, line 19
def self.schema_for(klass, *attributes)
  model = klass
  klasses = [klass]
  while klass != klass.base_class
    klass = klass.superclass
    klasses << klass
  end
  klasses.each do |kls|
    schema_klass = "#{kls.name}Schema".safe_constantize
    if schema_klass
      return kls.try(:abstract_class?) ? schema_klass.new(model, *attributes) : schema_klass.new(*attributes)
    end
  end
  AzaharaSchema::Schema.new(model, *attributes)
end

Public Instance Methods

add_filter(name, operator, values) click to toggle source
# File lib/azahara_schema/schema.rb, line 143
def add_filter(name, operator, values)
  raise 'filter ('+name+') is not defined!' unless available_filters.key?(name)
  filters[name] = { o: operator, v: values }
end
add_short_filter(name, str) click to toggle source

ACCESSORS

# File lib/azahara_schema/schema.rb, line 133
def add_short_filter(name, str)
  attrs = str.split('|')
  if attrs.size == 2
    operator, values = attrs
  elsif attrs.size == 1
    operator, values = '=', attrs.first
  end
  add_filter(name, operator, values.split('\\'))
end
add_sort(name, order=:asc) click to toggle source
# File lib/azahara_schema/schema.rb, line 148
def add_sort(name, order=:asc)
  sort[name] = order
end
as_json(options={}) click to toggle source
# File lib/azahara_schema/schema.rb, line 318
def as_json(options={})
  build_json_options!(options)
  entities.collect{|entity| entity_as_json(entity, options) }
end
association_path() click to toggle source
# File lib/azahara_schema/schema.rb, line 209
def association_path
  @association_path ||= parent_schema ? ( parent_schema.association_path + [association.name] ) : [model.model_name.element.to_sym]
end
attribute(name) click to toggle source
# File lib/azahara_schema/schema.rb, line 166
def attribute(name)
  available_attributes.detect{|att| att.name == name}
end
attribute_for_column(col) click to toggle source
# File lib/azahara_schema/schema.rb, line 225
def attribute_for_column(col)
  self.class.attribute_for_column(model, col)
end
available_associations() click to toggle source
# File lib/azahara_schema/schema.rb, line 213
def available_associations
  return [] unless include_associated_attributes?
  @available_associations ||= model.reflect_on_all_associations.select do |association|
    !association.options[:polymorphic] &&
      association.klass != model &&
      !association_path.include?( association.name.to_s.singularize.to_sym ) &&
      !association_path.include?( association.name.to_s.pluralize.to_sym )
  end.collect do |association|
    AzaharaSchema::Schema.schema_for(association.klass, parent_schema: self, association: association, relations_depth: nested_relations_depth.try(:-, 1))
  end
end
available_attributes() click to toggle source
# File lib/azahara_schema/schema.rb, line 170
def available_attributes
  unless @available_attributes
    initialize_available_attributes
    @available_attributes.each{|at| at.table_alias = Array(association_path[1..-1]).collect(&:to_s).join('_').presence }
  end
  @available_attributes
end
available_attributes_hash() click to toggle source
# File lib/azahara_schema/schema.rb, line 178
def available_attributes_hash
  available_attributes.inject({}){|obj, aa| obj[aa.name] = aa; obj }
end
available_columns() click to toggle source
# File lib/azahara_schema/schema.rb, line 182
def available_columns
  @available_columns ||= available_attributes.select{|att| att.column? }
end
available_filters() click to toggle source
# File lib/azahara_schema/schema.rb, line 201
def available_filters
  @available_filters ||= available_attributes_hash
end
base_scope() click to toggle source
# File lib/azahara_schema/schema.rb, line 252
def base_scope
  model.all
end
build_json_options!(options={}) click to toggle source
# File lib/azahara_schema/schema.rb, line 294
def build_json_options!(options={})
  columns.each{|col| col.build_json_options!(options) }
  options
end
collapsable_filters() click to toggle source
# File lib/azahara_schema/schema.rb, line 370
def collapsable_filters
  available_filters
end
column_names() click to toggle source
# File lib/azahara_schema/schema.rb, line 88
def column_names
  @column_names ||= default_columns
end
column_names=(values) click to toggle source
# File lib/azahara_schema/schema.rb, line 83
def column_names=(values)
  @column_names = values
  @columns = nil
end
columns() click to toggle source
# File lib/azahara_schema/schema.rb, line 92
def columns
  @columns ||= available_attributes_hash.slice(*column_names).values
end
default_columns() click to toggle source
# File lib/azahara_schema/schema.rb, line 110
def default_columns
  [main_attribute_name]
end
default_outputs() click to toggle source

DEFAULTS

# File lib/azahara_schema/schema.rb, line 106
def default_outputs
  [AzaharaSchema::Outputs.registered_outputs.keys.first].compact
end
default_sort() click to toggle source
# File lib/azahara_schema/schema.rb, line 114
def default_sort
  {}
end
disabled_filters() click to toggle source
# File lib/azahara_schema/schema.rb, line 190
def disabled_filters
  []
end
enabled_filter_names() click to toggle source
# File lib/azahara_schema/schema.rb, line 194
def enabled_filter_names
  names = self.class.enabled_filters if self.class.enabled_filters.any?
  names ||= available_attributes_hash.keys
  names &= enabled_filters if enabled_filters
  names -= disabled_filters
end
enabled_filters() click to toggle source
# File lib/azahara_schema/schema.rb, line 186
def enabled_filters

end
entities() click to toggle source
# File lib/azahara_schema/schema.rb, line 280
def entities
  scope = filtered_scope
  columns.each do |col|
    scope = col.add_preload(scope)
  end
  sort.keys.reverse.each do |name|
    att = attribute(name)
    scope = att.add_sort(scope, sort[name]) if att
  end
  scope = scope.offset(offset) if offset
  scope = scope.limit(limit) if limit
  scope
end
entity_as_json(entity, options=nil) click to toggle source
# File lib/azahara_schema/schema.rb, line 299
def entity_as_json(entity, options=nil)
  attr_hash = entity.as_json(options)
  # TODO serializable_add_includes(options) do |association, records, opts|
  columns.each do |col|
    col_sub_hash = attr_hash
    sub_col = col
    while sub_col.is_a?(AzaharaSchema::AssociationAttribute)
      col_sub_hash = (col_sub_hash[sub_col.association.name.to_s] ||= {})
      sub_col = sub_col.attribute
    end
    if col.type == 'love'
      col_sub_hash[sub_col.name] = sub_col.available_values.detect{|l, v| v == col_sub_hash[sub_col.name] }.try(:[], 0)
    else
      col_sub_hash[sub_col.name] = col.value(entity)
    end
  end
  attr_hash
end
entity_count() click to toggle source
# File lib/azahara_schema/schema.rb, line 276
def entity_count
  filtered_scope.count
end
entity_scope(scope=base_scope) click to toggle source
# File lib/azahara_schema/schema.rb, line 256
def entity_scope(scope=base_scope)
  scope = scope.visible if scope.respond_to?(:visible)
  scope = scope.send(self.default_scope) if self.default_scope
  scope
end
filtered_scope() click to toggle source
# File lib/azahara_schema/schema.rb, line 262
def filtered_scope
  scope = entity_scope
  filters.each do |name, attrs|
    scope = available_filters[name].add_statement(scope, attrs[:o], attrs[:v])
  end
  if (tokens = tokenize_search_query)
    searchable_attributes.each{|a| scope = a.add_join(scope) }
    arl = searchable_attributes[0].arel_statement('~', tokens) if searchable_attributes.any?
    Array(searchable_attributes[1..-1]).each{|att| arl = arl.or( att.arel_statement('~', tokens) ) }
    scope = scope.where(arl)
  end
  scope
end
filters() click to toggle source
# File lib/azahara_schema/schema.rb, line 96
def filters
  @filters ||= {}
end
from_params(params) click to toggle source

serialization

# File lib/azahara_schema/schema.rb, line 325
def from_params(params)
  if params[:f]
    filter_params = params[:f].permit(available_filters.keys + [available_filters.keys.inject({}){|o,name| o[name] = []; o }]).to_h
    filter_params.each do |name, filter_value|
      next if filter_value.blank?
      if filter_value.is_a?(Array)
        add_filter(name, '=', filter_value)
      else
        add_short_filter(name, filter_value)
      end
    end
  end
  if params[:c].is_a?(Array)
    self.column_names = params[:c].to_a
  end
  if params[:sort]
    @sort = nil
    params[:sort].each do |k, sort|
      add_sort(sort[:path], sort['desc'] == 'true' ? :desc : :asc )
    end
  end
  self.default_scope = params[:default_scope] if params[:default_scope]
  self.search_query = params[:q] unless params[:q].blank?
  self.offset = params[:offset] if params[:offset]
  self.limit = params[:limit] if params[:limit]
end
include_associated_attributes?() click to toggle source
# File lib/azahara_schema/schema.rb, line 127
def include_associated_attributes?
  nested_relations_depth > 0
end
initialize_available_attributes() click to toggle source
# File lib/azahara_schema/schema.rb, line 229
def initialize_available_attributes
  @available_attributes ||= []
  model.columns.each do |col|
    @available_attributes << attribute_for_column(col)
  end
  available_associations.each do |asoc_schema|
    asoc_schema.available_attributes.each do |asoc_attribute|
      next if asoc_attribute.is_a?(AggregationAttribute)
      added_attribute = AssociationAttribute.new(model, asoc_schema, asoc_attribute)
      @available_attributes << added_attribute
      @available_attributes << AggregationAttribute.new(model, added_attribute) if asoc_attribute.aggregable?
    end
  end
end
main_attribute_name() click to toggle source

just a dummy implementation

# File lib/azahara_schema/schema.rb, line 119
def main_attribute_name
  available_attributes.detect{|att| att.name != 'id' }.name
end
nested_relations_depth() click to toggle source
# File lib/azahara_schema/schema.rb, line 123
def nested_relations_depth
  @nested_relations_depth || 4
end
operator_for(fname) click to toggle source
# File lib/azahara_schema/schema.rb, line 152
def operator_for(fname)
  filters[fname] && filters[fname][:o]
end
operators_for(filter_name) click to toggle source
# File lib/azahara_schema/schema.rb, line 160
def operators_for(filter_name)
  operators = available_filters[filter_name] && available_filters[filter_name].available_operators
  operators &= self.class.operators_for_filters[filter_name] if operators && self.class.operators_for_filters[filter_name]
  operators
end
outputs() click to toggle source
# File lib/azahara_schema/schema.rb, line 244
def outputs
  Outputs.new(self)
end
searchable_attributes() click to toggle source
# File lib/azahara_schema/schema.rb, line 79
def searchable_attributes
  @searchable_attributes ||= available_attributes.select{|a| a.searchable? }
end
sort() click to toggle source
# File lib/azahara_schema/schema.rb, line 100
def sort
  @sort ||= ActiveSupport::OrderedHash.new.merge!(default_sort)
end
to_param() click to toggle source
# File lib/azahara_schema/schema.rb, line 352
def to_param
  params = {}
  params[:f] = {}
  filters.each do |fname, attrs|
    params[:f][fname] = "#{attrs[:o]}|#{Array(attrs[:v]).collect{|v| v.to_s}.join('\\')}"
  end
  params[:default_scope] = default_scope if default_scope
  params[:c] = column_names
  params[:q] = search_query if params[:q]
  params[:offset] = offset
  params[:limit] = limit
  params
end
tokenize_search_query(query=search_query) click to toggle source
# File lib/azahara_schema/schema.rb, line 248
def tokenize_search_query(query=search_query)
  query.split if query
end
uncollapsable_filters() click to toggle source
# File lib/azahara_schema/schema.rb, line 366
def uncollapsable_filters
  {}
end
user_available_filters() click to toggle source
# File lib/azahara_schema/schema.rb, line 205
def user_available_filters
  available_filters.slice(*enabled_filter_names)
end
value_for(fname) click to toggle source
# File lib/azahara_schema/schema.rb, line 156
def value_for(fname)
  filters[fname] && filters[fname][:v]
end