module ActiveRecord::VirtualAttributes::VirtualDelegates
VirtualDelegate is the same as delegate, but adds sql support, and a default when a value is not found
Model.belongs_to :association Model.virtual_delegate :field1, :field2, to: :association
Model.select(:field1) # now works
Public Class Methods
select_from_alias(to_ref, col, to_model_col_name, src_model_id) { |arel| ... }
click to toggle source
Based upon ActiveRecord
AssociationScope.scope
# File lib/active_record/virtual_attributes/virtual_delegates.rb, line 244 def self.select_from_alias(to_ref, col, to_model_col_name, src_model_id) query = if to_ref.scope to_ref.klass.instance_exec(nil, &to_ref.scope) else to_ref.klass.all end src_model = to_ref.active_record to_table = select_from_alias_table(to_ref.klass, src_model_id.relation) to_model_id = to_ref.klass.arel_attribute(to_model_col_name, to_table) to_column = to_ref.klass.arel_attribute(col, to_table) arel = query.except(:select).select(to_column).arel .from(to_table) .where(to_model_id.eq(src_model_id)) # :type is in the reflection definition (meaning it is polymorphic) if to_ref.type # get the class name (e.g. "Host") polymorphic_type = src_model.base_class.name arel = arel.where(to_ref.klass.arel_attribute(to_ref.type).eq(polymorphic_type)) end yield arel if block_given? Arel.sql("(#{arel.to_sql})") end
select_from_alias_table(to_klass, src_relation)
click to toggle source
determine table reference to use for a sub query
typically to_table is just the table used for the to_ref but if it is a self join, then it will also have an alias
# File lib/active_record/virtual_attributes/virtual_delegates.rb, line 275 def self.select_from_alias_table(to_klass, src_relation) to_table = to_klass.arel_table # if a self join, alias the second table to a different name if to_table.table_name == src_relation.table_name # use a dup to not modify the primary table in the model to_table = to_table.dup # use a table alias to not conflict with table name in the primary query to_table.table_alias = "#{to_table.table_name}_sub" end to_table end