Class: ActiveRecord::Associations::HasManyThroughAssociation
- Inherits:
-
AssociationProxy
- Object
- AssociationProxy
- ActiveRecord::Associations::HasManyThroughAssociation
- Defined in:
- lib/active_record/associations/has_many_through_association.rb
Overview
:nodoc:
Instance Attribute Summary
Attributes inherited from AssociationProxy
Instance Method Summary collapse
-
#<<(*records) ⇒ Object
Adds records to the association.
- #build(attrs = nil) ⇒ Object
- #count(*args) ⇒ Object
- #create!(attrs = nil) ⇒ Object
-
#delete(*records) ⇒ Object
Remove
records
from this association. - #find(*args) ⇒ Object
-
#initialize(owner, reflection) ⇒ HasManyThroughAssociation
constructor
A new instance of HasManyThroughAssociation.
- #reset ⇒ Object
-
#sum(*args, &block) ⇒ Object
Calculate sum using SQL, not Enumerable.
Methods inherited from AssociationProxy
#===, #aliased_table_name, #loaded, #loaded?, #proxy_owner, #proxy_reflection, #proxy_respond_to?, #proxy_target, #reload, #respond_to?, #target, #target=
Constructor Details
#initialize(owner, reflection) ⇒ HasManyThroughAssociation
Returns a new instance of HasManyThroughAssociation.
4 5 6 7 8 9 |
# File 'lib/active_record/associations/has_many_through_association.rb', line 4 def initialize(owner, reflection) super reflection.check_validity! @finder_sql = construct_conditions construct_sql end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args, &block) ⇒ Object (protected)
116 117 118 119 120 121 122 |
# File 'lib/active_record/associations/has_many_through_association.rb', line 116 def method_missing(method, *args, &block) if @target.respond_to?(method) || (!@reflection.klass.respond_to?(method) && Class.respond_to?(method)) super else @reflection.klass.with_scope(construct_scope) { @reflection.klass.send(method, *args, &block) } end end |
Instance Method Details
#<<(*records) ⇒ Object
Adds records to the association. The source record and its associates must have ids in order to create records associating them, so this will raise ActiveRecord::HasManyThroughCantAssociateNewRecords if either is a new record. Calls create! so you can rescue errors.
The :before_add and :after_add callbacks are not yet supported.
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/active_record/associations/has_many_through_association.rb', line 49 def <<(*records) return if records.empty? through = @reflection.through_reflection raise ActiveRecord::HasManyThroughCantAssociateNewRecords.new(@owner, through) if @owner.new_record? load_target klass = through.klass klass.transaction do flatten_deeper(records).each do |associate| raise_on_type_mismatch(associate) raise ActiveRecord::HasManyThroughCantAssociateNewRecords.new(@owner, through) unless associate.respond_to?(:new_record?) && !associate.new_record? @owner.send(@reflection.through_reflection.name).proxy_target << klass.with_scope(:create => construct_join_attributes(associate)) { klass.create! } @target << associate end end self end |
#build(attrs = nil) ⇒ Object
90 91 92 |
# File 'lib/active_record/associations/has_many_through_association.rb', line 90 def build(attrs = nil) raise ActiveRecord::HasManyThroughCantAssociateNewRecords.new(@owner, @reflection.through_reflection) end |
#count(*args) ⇒ Object
105 106 107 108 109 110 111 112 113 |
# File 'lib/active_record/associations/has_many_through_association.rb', line 105 def count(*args) column_name, = @reflection.klass.send(:construct_count_options_from_legacy_args, *args) if @reflection.[:uniq] # This is needed becase 'SELECT count(DISTINCT *)..' is not valid sql statement. column_name = "#{@reflection.klass.table_name}.#{@reflection.klass.primary_key}" if column_name == :all .merge!(:distinct => true) end @reflection.klass.send(:with_scope, construct_scope) { @reflection.klass.count(column_name, ) } end |
#create!(attrs = nil) ⇒ Object
94 95 96 97 98 |
# File 'lib/active_record/associations/has_many_through_association.rb', line 94 def create!(attrs = nil) @reflection.klass.transaction do self << @reflection.klass.with_scope(:create => attrs) { @reflection.klass.create! } end end |
#delete(*records) ⇒ Object
Remove records
from this association. Does not destroy records
.
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/active_record/associations/has_many_through_association.rb', line 73 def delete(*records) records = flatten_deeper(records) records.each { |associate| raise_on_type_mismatch(associate) } records.reject! { |associate| @target.delete(associate) if associate.new_record? } return if records.empty? @delete_join_finder ||= "find_all_by_#{@reflection.source_reflection.association_foreign_key}" through = @reflection.through_reflection through.klass.transaction do records.each do |associate| joins = @owner.send(through.name).send(@delete_join_finder, associate.id) @owner.send(through.name).delete(joins) @target.delete(associate) end end end |
#find(*args) ⇒ Object
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/active_record/associations/has_many_through_association.rb', line 11 def find(*args) = Base.send(:extract_options_from_args!, args) conditions = "#{@finder_sql}" if sanitized_conditions = sanitize_sql([:conditions]) conditions << " AND (#{sanitized_conditions})" end [:conditions] = conditions if [:order] && @reflection.[:order] [:order] = "#{[:order]}, #{@reflection.[:order]}" elsif @reflection.[:order] [:order] = @reflection.[:order] end [:select] = construct_select([:select]) [:from] ||= construct_from [:joins] = construct_joins([:joins]) [:include] = @reflection.source_reflection.[:include] if [:include].nil? () # Pass through args exactly as we received them. args << @reflection.klass.find(*args) end |
#reset ⇒ Object
38 39 40 41 |
# File 'lib/active_record/associations/has_many_through_association.rb', line 38 def reset @target = [] @loaded = false end |
#sum(*args, &block) ⇒ Object
Calculate sum using SQL, not Enumerable
101 102 103 |
# File 'lib/active_record/associations/has_many_through_association.rb', line 101 def sum(*args, &block) calculate(:sum, *args, &block) end |