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
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 |
# File 'lib/active_record/virtual_attributes/virtual_delegates.rb', line 240 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
271 272 273 274 275 276 277 278 279 280 281 |
# File 'lib/active_record/virtual_attributes/virtual_delegates.rb', line 271 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 |