# File lib/datasource/adapters/active_record.rb, line 299 def primary_scope_table(ds) ds.scope.klass.table_name end
module Datasource::Adapters::ActiveRecord
Public Instance Methods
association_klass(reflection)
click to toggle source
# File lib/datasource/adapters/active_record.rb, line 174 def association_klass(reflection) if reflection.macro == :belongs_to && reflection.options[:polymorphic] fail Datasource::Error, "polymorphic belongs_to not supported, write custom loader" else reflection.klass end end
association_loaded?(records, name, assoc_select)
click to toggle source
# File lib/datasource/adapters/active_record.rb, line 182 def association_loaded?(records, name, assoc_select) if records.first.association(name).loaded? all_loaded = records.all? { |record| record.association(name).loaded? } if assoc_select == ["*"] all_loaded elsif all_loaded records.all? do |record| assoc_sample = Array(record.send(name)).first assoc_sample.nil? || assoc_sample._datasource_instance end else false end else false end end
association_reflection(klass, name)
click to toggle source
# File lib/datasource/adapters/active_record.rb, line 140 def association_reflection(klass, name) if reflection = klass.reflect_on_association(name) { klass: reflection.klass, macro: reflection.macro, foreign_key: reflection.try(:foreign_key) } end end
ensure_table_join!(ds, name, att)
click to toggle source
# File lib/datasource/adapters/active_record.rb, line 303 def ensure_table_join!(ds, name, att) join_value = ds.scope.joins_values.find do |value| if value.is_a?(Symbol) value.to_s == att[:name] elsif value.is_a?(String) if value =~ /join (\w+)/i $1 == att[:name] end end end fail Datasource::Error, "given scope does not join on #{name}, but it is required by #{att[:name]}" unless join_value end
get_rows(ds)
click to toggle source
# File lib/datasource/adapters/active_record.rb, line 280 def get_rows(ds) append_select = [] ds.expose_associations.each_pair do |assoc_name, assoc_select| if reflection = association_reflection(ds.class.orm_klass, assoc_name.to_sym) Datasource::Base.reflection_select(reflection, append_select, []) end end ds.select(*append_select) scope = select_scope(ds) if scope.respond_to?(:datasource_set) scope = scope.spawn.datasource_set(datasource_class: nil) end scope.includes_values = [] scope.to_a.tap do |records| load_associations(ds, records) end end
get_table_name(klass)
click to toggle source
# File lib/datasource/adapters/active_record.rb, line 150 def get_table_name(klass) klass.table_name.to_sym end
has_attribute?(record, name)
click to toggle source
# File lib/datasource/adapters/active_record.rb, line 170 def has_attribute?(record, name) record.attributes.key?(name.to_s) end
is_scope?(obj)
click to toggle source
# File lib/datasource/adapters/active_record.rb, line 154 def is_scope?(obj) obj.kind_of?(::ActiveRecord::Relation) end
load_association(records, name, assoc_select, params)
click to toggle source
# File lib/datasource/adapters/active_record.rb, line 200 def load_association(records, name, assoc_select, params) return if records.empty? name = name.to_sym klass = records.first.class if reflection = klass.reflect_on_association(name) assoc_class = association_klass(reflection) datasource_class = assoc_class.default_datasource scope = assoc_class.all datasource = datasource_class.new(scope) assoc_select_attributes = assoc_select.reject { |att| att.kind_of?(Hash) } assoc_select_associations = assoc_select.inject({}) do |hash, att| hash.deep_merge!(att) if att.kind_of?(Hash) hash end Datasource::Base.reflection_select(association_reflection(klass, name), [], assoc_select_attributes) datasource.params(params) Datasource.logger.debug { "load_association #{records.first.try!(:class)} #{name}: #{assoc_select_attributes.inspect}" } datasource.select(*assoc_select_attributes) select_values = datasource.get_select_values # TODO: manually load associations, and load them all at once for # nested associations, eg. in following, load all Users in 1 query: # {"user"=>["*"], "players"=>["*"], "picked_players"=>["*", # {:position=>["*"]}], "parent_picked_team"=>["*", {:user=>["*"]}]} begin ::ActiveRecord::Associations::Preloader .new.preload(records, name, assoc_class.select(*select_values)) rescue ArgumentError ::ActiveRecord::Associations::Preloader .new(records, name, assoc_class.select(*select_values)).run end assoc_records = records.flat_map { |record| record.send(name) }.compact unless assoc_records.empty? if Datasource.logger.info? && !assoc_select_associations.empty? Datasource.logger.info { "Loading associations " + assoc_select_associations.keys.map(&:to_s).join(", ") + " for #{assoc_records.first.try!(:class)}s" } end assoc_select_associations.each_pair do |assoc_name, assoc_select| Datasource.logger.debug { "load_association nested association #{assoc_name}: #{assoc_select.inspect}" } load_association(assoc_records, assoc_name, assoc_select, params) end datasource.results(assoc_records) end end rescue Exception => ex if ex.is_a?(SystemStackError) || ex.is_a?(Datasource::RecursionError) fail Datasource::RecursionError, "recursive association (involving #{name})" else raise end end
load_associations(ds, records)
click to toggle source
# File lib/datasource/adapters/active_record.rb, line 270 def load_associations(ds, records) if Datasource.logger.info? && !ds.expose_associations.empty? Datasource.logger.info { "Loading associations " + ds.expose_associations.keys.map(&:to_s).join(", ") + " for #{records.first.try!(:class)}s" } end Datasource.logger.debug { "load_associations (#{records.size} #{records.first.try!(:class)}): #{ds.expose_associations.inspect}" } ds.expose_associations.each_pair do |assoc_name, assoc_select| load_association(records, assoc_name, assoc_select, ds.params) end end
primary_scope_table(ds)
click to toggle source
scope_loaded?(scope)
click to toggle source
# File lib/datasource/adapters/active_record.rb, line 162 def scope_loaded?(scope) scope.loaded? end
scope_to_class(scope)
click to toggle source
# File lib/datasource/adapters/active_record.rb, line 158 def scope_to_class(scope) scope.klass end
scope_to_records(scope)
click to toggle source
# File lib/datasource/adapters/active_record.rb, line 166 def scope_to_records(scope) scope.to_a end
select_scope(ds)
click to toggle source
# File lib/datasource/adapters/active_record.rb, line 260 def select_scope(ds) ds.scope.select(*ds.get_select_values) end
to_query(ds)
click to toggle source
# File lib/datasource/adapters/active_record.rb, line 254 def to_query(ds) ::ActiveRecord::Base.uncached do ds.scope.select(*ds.get_select_values).to_sql end end
upgrade_records(ds, records)
click to toggle source
# File lib/datasource/adapters/active_record.rb, line 264 def upgrade_records(ds, records) Datasource.logger.debug { "Upgrading records #{records.map(&:class).map(&:name).join(', ')}" } load_associations(ds, records) ds.results(records) end