module Graphoid::ActiveRecordDriver
Public Class Methods
belongs_to?(type)
click to toggle source
# File lib/graphoid/drivers/active_record.rb, line 18 def belongs_to?(type) type == ActiveRecord::Reflection::BelongsToReflection end
class_of(relation)
click to toggle source
# File lib/graphoid/drivers/active_record.rb, line 56 def class_of(relation) { ActiveRecord::Reflection::HasAndBelongsToManyReflection => ManyToMany, ActiveRecord::Reflection::BelongsToReflection => BelongsTo, ActiveRecord::Reflection::ThroughReflection => ManyToMany, ActiveRecord::Reflection::HasManyReflection => HasMany, ActiveRecord::Reflection::HasOneReflection => HasOne }[relation.class] || Relation end
eager_load(selection, model)
click to toggle source
# File lib/graphoid/drivers/active_record.rb, line 101 def eager_load(selection, model) nodes = selection.ast_node.selections.first.selections nodes.select!{ |n| !n.selections.empty? } include_array = generate_array(nodes) include_array.empty? ? model : model.includes(*include_array) end
embedded_in?(_type)
click to toggle source
# File lib/graphoid/drivers/active_record.rb, line 34 def embedded_in?(_type) false end
embeds_many?(_type)
click to toggle source
# File lib/graphoid/drivers/active_record.rb, line 30 def embeds_many?(_type) false end
embeds_one?(_type)
click to toggle source
# File lib/graphoid/drivers/active_record.rb, line 26 def embeds_one?(_type) false end
execute_and(scope, parsed)
click to toggle source
# File lib/graphoid/drivers/active_record.rb, line 108 def execute_and(scope, parsed) scope.where(parsed) end
execute_or(scope, list)
click to toggle source
# File lib/graphoid/drivers/active_record.rb, line 112 def execute_or(scope, list) list.map! do |object| Graphoid::Queries::Processor.execute(scope, object) end list.reduce(:or) end
fields_of(model)
click to toggle source
# File lib/graphoid/drivers/active_record.rb, line 70 def fields_of(model) model.columns end
generate_array(nodes)
click to toggle source
# File lib/graphoid/drivers/active_record.rb, line 86 def generate_array(nodes) include_array = [] nodes.each do |node| children = node.selections.select!{ |n| !n.selections.empty? } if children.empty? include_array.push(node.name.to_sym) else include_array.push(node.name.to_sym => generate_array(children)) end end include_array end
has_and_belongs_to_many?(type)
click to toggle source
# File lib/graphoid/drivers/active_record.rb, line 10 def has_and_belongs_to_many?(type) type == ActiveRecord::Reflection::HasAndBelongsToManyReflection end
has_many?(type)
click to toggle source
# File lib/graphoid/drivers/active_record.rb, line 14 def has_many?(type) type == ActiveRecord::Reflection::HasManyReflection end
has_one?(type)
click to toggle source
# File lib/graphoid/drivers/active_record.rb, line 22 def has_one?(type) type == ActiveRecord::Reflection::HasOneReflection end
inverse_name_of(relation)
click to toggle source
# File lib/graphoid/drivers/active_record.rb, line 66 def inverse_name_of(relation) relation.inverse_of&.class_name&.underscore end
parse(attribute, value, operator)
click to toggle source
# File lib/graphoid/drivers/active_record.rb, line 119 def parse(attribute, value, operator) field = attribute.name case operator when 'not' parsed = ["#{field} != ?", value] parsed = ["#{field} not like ?", value.to_s] if attribute.type == :string parsed = ["#{field} is not null"] if value.nil? when 'contains', 'regex' parsed = ["#{field} like ?", "%#{value}%"] when 'gt', 'gte', 'lt', 'lte', 'not', 'in', 'nin' operator = { gt: '>', gte: '>=', lt: '<', lte: '<=', in: 'in', nin: 'not in' }[operator.to_sym] parsed = ["#{field} #{operator} (?)", value] else parsed = ["#{field} = ?", value] end parsed end
relate_many(scope, relation, value, operator)
click to toggle source
# File lib/graphoid/drivers/active_record.rb, line 148 def relate_many(scope, relation, value, operator) parsed = {} field_name = relation.inverse_name || scope.name.underscore target = Graphoid::Queries::Processor.execute(relation.klass, value).to_a if relation.many_to_many? field_name = field_name.to_s.singularize + '_ids' ids = target.map(&field_name.to_sym) ids.flatten!.uniq! else field_name = :"#{field_name}_id" ids = target.map(&field_name) end if operator == 'none' parsed = ['id not in (?)', ids] if ids.present? elsif operator == 'some' parsed = ['id in (?)', ids] elsif operator == 'every' # the following process is a SQL division # the amount of queries it executes is on per row # it is the same than doing an iteration process # that iteration process would work in mongoid too # TODO: check and fix this query for many to many relations plural_name = relation.name.pluralize conditions = value.map do |_key, _value| operation = Operation.new(relation.klass, _key, _value) parsed = parse(operation.operand, operation.value, operation.operator) val = parsed.last.is_a?(String) ? "'#{parsed.last}'" : parsed.last parsed = parsed.first.sub('?', val) " AND #{parsed}" end.join query = " SELECT count(id) as total, #{field_name} FROM #{plural_name} A GROUP BY #{field_name} HAVING total = ( SELECT count(id) FROM #{plural_name} B WHERE B.#{field_name} = A.#{field_name} #{conditions} ) " result = ActiveRecord::Base.connection.execute(query) ids = result.map { |row| row[field_name.to_s] } parsed = ['id in (?)', ids] end parsed end
relate_through(scope, relation, value)
click to toggle source
TODO: fix this as it is unused
# File lib/graphoid/drivers/active_record.rb, line 138 def relate_through(scope, relation, value) # if relation.has_one_through? # ids = Graphoid::Queries::Processor.execute(relation.klass, value).to_a.map(&:id) # through = relation.source.options[:through].to_s.camelize.constantize # ids = through.where(id: ids) # ids = Graphoid::Queries::Processor.execute(relation.klass, value).to_a.map(&:id) # parsed = *["#{field.underscore}_id in (?)", ids] # end end
relation_type(relation)
click to toggle source
# File lib/graphoid/drivers/active_record.rb, line 82 def relation_type(relation) relation.class end
relations_of(model)
click to toggle source
# File lib/graphoid/drivers/active_record.rb, line 74 def relations_of(model) model.reflections end
skip(result, skip)
click to toggle source
# File lib/graphoid/drivers/active_record.rb, line 78 def skip(result, skip) result.offset(skip) end
through?(type)
click to toggle source
# File lib/graphoid/drivers/active_record.rb, line 6 def through?(type) type == ActiveRecord::Reflection::ThroughReflection end
types_map()
click to toggle source
# File lib/graphoid/drivers/active_record.rb, line 38 def types_map { binary: GraphQL::Types::Boolean, boolean: GraphQL::Types::Boolean, float: GraphQL::Types::Float, integer: GraphQL::Types::Int, string: GraphQL::Types::String, datetime: Graphoid::Scalars::DateTime, date: Graphoid::Scalars::DateTime, time: Graphoid::Scalars::DateTime, timestamp: Graphoid::Scalars::DateTime, text: Graphoid::Scalars::Text, bigint: Graphoid::Scalars::BigInt, decimal: Graphoid::Scalars::Decimal } end