Module: Graphoid::ActiveRecordDriver
- Defined in:
- lib/graphoid/drivers/active_record.rb
Class Method Summary collapse
- .belongs_to?(type) ⇒ Boolean
- .class_of(relation) ⇒ Object
- .eager_load(selection, model) ⇒ Object
- .embedded_in?(_type) ⇒ Boolean
- .embeds_many?(_type) ⇒ Boolean
- .embeds_one?(_type) ⇒ Boolean
- .execute_and(scope, parsed) ⇒ Object
- .execute_or(scope, list) ⇒ Object
- .fields_of(model) ⇒ Object
- .generate_array(nodes) ⇒ Object
- .has_and_belongs_to_many?(type) ⇒ Boolean
- .has_many?(type) ⇒ Boolean
- .has_one?(type) ⇒ Boolean
- .inverse_name_of(relation) ⇒ Object
- .parse(attribute, value, operator) ⇒ Object
- .relate_many(scope, relation, value, operator) ⇒ Object
-
.relate_through(scope, relation, value) ⇒ Object
TODO: fix this as it is unused.
- .relation_type(relation) ⇒ Object
- .relations_of(model) ⇒ Object
- .skip(result, skip) ⇒ Object
- .through?(type) ⇒ Boolean
- .types_map ⇒ Object
Class Method Details
.belongs_to?(type) ⇒ Boolean
18 19 20 |
# File 'lib/graphoid/drivers/active_record.rb', line 18 def belongs_to?(type) type == ActiveRecord::Reflection::BelongsToReflection end |
.class_of(relation) ⇒ Object
56 57 58 59 60 61 62 63 64 |
# 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) ⇒ Object
101 102 103 104 105 106 |
# 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) ⇒ Boolean
34 35 36 |
# File 'lib/graphoid/drivers/active_record.rb', line 34 def (_type) false end |
.embeds_many?(_type) ⇒ Boolean
30 31 32 |
# File 'lib/graphoid/drivers/active_record.rb', line 30 def (_type) false end |
.embeds_one?(_type) ⇒ Boolean
26 27 28 |
# File 'lib/graphoid/drivers/active_record.rb', line 26 def (_type) false end |
.execute_and(scope, parsed) ⇒ Object
108 109 110 |
# File 'lib/graphoid/drivers/active_record.rb', line 108 def execute_and(scope, parsed) scope.where(parsed) end |
.execute_or(scope, list) ⇒ Object
112 113 114 115 116 117 |
# 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) ⇒ Object
70 71 72 |
# File 'lib/graphoid/drivers/active_record.rb', line 70 def fields_of(model) model.columns end |
.generate_array(nodes) ⇒ Object
86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# 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) ⇒ Boolean
10 11 12 |
# File 'lib/graphoid/drivers/active_record.rb', line 10 def has_and_belongs_to_many?(type) type == ActiveRecord::Reflection::HasAndBelongsToManyReflection end |
.has_many?(type) ⇒ Boolean
14 15 16 |
# File 'lib/graphoid/drivers/active_record.rb', line 14 def has_many?(type) type == ActiveRecord::Reflection::HasManyReflection end |
.has_one?(type) ⇒ Boolean
22 23 24 |
# File 'lib/graphoid/drivers/active_record.rb', line 22 def has_one?(type) type == ActiveRecord::Reflection::HasOneReflection end |
.inverse_name_of(relation) ⇒ Object
66 67 68 |
# 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) ⇒ Object
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# 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) ⇒ Object
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 |
# 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) ⇒ Object
TODO: fix this as it is unused
138 139 140 141 142 143 144 145 146 |
# 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) ⇒ Object
82 83 84 |
# File 'lib/graphoid/drivers/active_record.rb', line 82 def relation_type(relation) relation.class end |
.relations_of(model) ⇒ Object
74 75 76 |
# File 'lib/graphoid/drivers/active_record.rb', line 74 def relations_of(model) model.reflections end |
.skip(result, skip) ⇒ Object
78 79 80 |
# File 'lib/graphoid/drivers/active_record.rb', line 78 def skip(result, skip) result.offset(skip) end |
.through?(type) ⇒ Boolean
6 7 8 |
# File 'lib/graphoid/drivers/active_record.rb', line 6 def through?(type) type == ActiveRecord::Reflection::ThroughReflection end |
.types_map ⇒ Object
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# 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 |