class Delta::SetOperator::ActiveRecord
Public Class Methods
compatible?(a, b)
click to toggle source
# File lib/delta/set_operator/active_record.rb, line 4 def self.compatible?(a, b) a.is_a?(b.class) && a.class.name.include?("ActiveRecord") end
new(a:, b:, identifiers: nil, changes:)
click to toggle source
Calls superclass method
Delta::SetOperator::new
# File lib/delta/set_operator/active_record.rb, line 8 def initialize(a:, b:, identifiers: nil, changes:) super self.identifiers = identifiers || [:id] end
Private Instance Methods
arel_table(scope, name)
click to toggle source
# File lib/delta/set_operator/active_record.rb, line 73 def arel_table(scope, name) Arel::Table.new(scope.arel_table.name, as: name) end
attribute_clause(a, b)
click to toggle source
# File lib/delta/set_operator/active_record.rb, line 61 def attribute_clause(a, b) changes.map { |k| a[k].not_eq(b[k]) }.inject(&:or) end
build_query(a_scope, b_scope, join_type)
click to toggle source
# File lib/delta/set_operator/active_record.rb, line 42 def build_query(a_scope, b_scope, join_type) a_query = nested_query(a_scope, "a") b_query = nested_query(b_scope, "b") a = arel_table(a_scope, "a") b = arel_table(b_scope, "b") query = a.from(a_query) query = query.join(b.join(b_query).join_sources, join_type) query = query.on(*identity_clauses(a, b)) query = query.group(*group_clauses(a, b)) query end
execute(query, scope)
click to toggle source
# File lib/delta/set_operator/active_record.rb, line 69 def execute(query, scope) model_for_scope(scope).find_by_sql(query.to_sql) end
group_clauses(a, _b)
click to toggle source
# File lib/delta/set_operator/active_record.rb, line 65 def group_clauses(a, _b) identifiers.map { |k| a[k] } end
identity_clauses(a, b)
click to toggle source
# File lib/delta/set_operator/active_record.rb, line 57 def identity_clauses(a, b) identifiers.map { |k| a[k].eq(b[k]) } end
inner_join()
click to toggle source
# File lib/delta/set_operator/active_record.rb, line 85 def inner_join Arel::Nodes::InnerJoin end
intersect(a_scope, b_scope)
click to toggle source
# File lib/delta/set_operator/active_record.rb, line 28 def intersect(a_scope, b_scope) return [] if changes.empty? a = arel_table(a_scope, "a") b = arel_table(b_scope, "b") query = build_query(a_scope, b_scope, inner_join) query = query.project(Arel.star) query = query.where(attribute_clause(a, b)) execute(query, a_scope) end
left_join()
click to toggle source
# File lib/delta/set_operator/active_record.rb, line 81 def left_join Arel::Nodes::OuterJoin end
model_for_scope(scope)
click to toggle source
# File lib/delta/set_operator/active_record.rb, line 89 def model_for_scope(scope) scope.respond_to?(:model) ? scope.model : scope.klass end
nested_query(scope, name)
click to toggle source
# File lib/delta/set_operator/active_record.rb, line 77 def nested_query(scope, name) Arel.sql("(#{scope.to_sql}) as #{name}") end
subtract(a_scope, b_scope)
click to toggle source
# File lib/delta/set_operator/active_record.rb, line 16 def subtract(a_scope, b_scope) a = arel_table(a_scope, "a") b = arel_table(b_scope, "b") query = build_query(a_scope, b_scope, left_join) query = query.project(a[Arel.star]) query = query.where(b[identifiers.first].eq(nil)) execute(query, a_scope) end