Module: ActiveRecord::VirtualAttributes::VirtualDelegates
- Extended by:
- ActiveSupport::Concern
- Included in:
- ActiveRecord::VirtualAttributes
- Defined in:
- lib/active_record/virtual_attributes/virtual_delegates.rb
Overview
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
Defined Under Namespace
Modules: ClassMethods
Class Method Summary collapse
-
.select_from_alias(to_ref, col, to_model_col_name, src_model_id) {|arel| ... } ⇒ Object
Based upon ActiveRecord AssociationScope.scope.
-
.select_from_alias_table(to_klass, src_relation) ⇒ Object
determine table reference to use for a sub query.
Class Method Details
.select_from_alias(to_ref, col, to_model_col_name, src_model_id) {|arel| ... } ⇒ Object
Based upon ActiveRecord AssociationScope.scope
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 |
# File 'lib/active_record/virtual_attributes/virtual_delegates.rb', line 220 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_table[to_model_col_name, to_table] to_column = to_ref.klass.arel_table[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_table[to_ref.type].eq(polymorphic_type)) end yield arel if block_given? arel end |
.select_from_alias_table(to_klass, src_relation) ⇒ Object
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
251 252 253 254 255 256 257 258 259 |
# File 'lib/active_record/virtual_attributes/virtual_delegates.rb', line 251 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.name == src_relation.name # use a table alias to not conflict with table name in the primary query to_table = to_table.alias("#{to_table.name}_sub") end to_table end |