class Clearly::Query::Definition
Validates and represents a model query specification definition.
Attributes
@return [Array<Symbol>] available model fields
@return [Array<Hash>] model associations hierarchy
@return [Array<Hash>] model associations flat array
@return [Hash] defaults
@return [Array<Hash>] mapped model fields
@return [Array<Array<Hash>>] associations organised to calculate joins
@return [ActiveRecord::Base] active record model for this definition
@return [Arel::Table] arel table for this definition
@return [Array<Symbol>] available text model fields
Public Class Methods
Create a Definition
@param [Hash] opts the options to create a message with. @option opts [ActiveRecord::Base] :model (nil) the ActiveRecord model @option opts [Hash] :hash (nil) the model definition hash @option opts [Arel::Table] :table (nil) the arel table @return [Clearly::Query::Definition]
# File lib/clearly/query/definition.rb, line 46 def initialize(opts) opts = {model: nil, hash: nil, table: nil}.merge(opts) # two ways to go: model and hash, or table and joins result = nil result = create_from_model(opts[:model], opts[:hash]) unless opts[:model].nil? result = create_from_table(opts[:table]) if result.nil? && !opts[:table].nil? fail Clearly::Query::QueryArgumentError.new('could not build definition from options') if result.nil? result end
Public Instance Methods
Build custom field from model mappings @param [Symbol] column_name @return [Arel::Nodes::Node, Arel::Attributes::Attribute, String]
# File lib/clearly/query/definition.rb, line 61 def get_field_mapping(column_name) value = @field_mappings[column_name] if @field_mappings.keys.include?(column_name) && !value.blank? value else nil end end
Private Instance Methods
Create a flat array of joins. @param [Array<Hash>] associations @return [Array<Hash>] associations
# File lib/clearly/query/definition.rb, line 144 def build_associations_flat(associations) joins = [] if associations.is_a?(Array) more_associations = associations.map { |i| build_associations_flat(i) } joins.push(*more_associations.flatten.compact) if more_associations.size > 0 elsif associations.is_a?(Hash) joins.push(associations.except(:associations)) if associations[:associations] && associations[:associations].size > 0 more_associations = build_associations_flat(associations[:associations]) joins.push(*more_associations.compact) if more_associations.size > 0 end end joins.uniq end
Create a Definition
from an ActiveRecord model. @param [ActiveRecord::Base] model the ActiveRecord model @param [Hash] hash the model definition hash @return [Clearly::Query::Definition]
# File lib/clearly/query/definition.rb, line 76 def create_from_model(model, hash) validate_model(model) validate_definition(hash) @model = model @table = relation_table(model) @all_fields = hash[:fields][:valid] @text_fields = hash[:fields][:text] mappings = {} hash[:fields][:mappings].each { |m| mappings[m[:name]] = m[:value] } @field_mappings = mappings @associations = hash[:associations] @associations_flat = build_associations_flat(@associations) if @associations.size > 0 node = {join: model, on: nil, associations: hash[:associations]} graph = Clearly::Query::Graph.new(node, :associations) @joins = graph.branches else @joins = [] end @defaults = hash[:defaults] self end
Create a Definition
for a has and belongs to many table. @param [Arel::Table] table the arel table @return [Clearly::Query::Definition]
# File lib/clearly/query/definition.rb, line 109 def create_from_table(table) validate_table(table) @model = nil @table = table @all_fields = [] @text_fields = [] @field_mappings = [] @associations = [] @associations_flat = [] @joins = [] @defaults = {} table_name = table.name associated_table_names = table_name.split('_') # assumes associated tables primary key is 'id' # assumes associated table names are the plural version of HABTM _id columns associated_table_names.each do |t| arel_table = Arel::Table.new(t.to_sym) id_column = "#{t.singularize}_id" join = {join: arel_table, on: arel_table[:id].eq(table[id_column]), available: true} @all_fields.push(id_column) @associations.push(join) @associations_flat.push(join) @joins.push([join]) end self end