Class: ActiveRecord::Associations::HasAndBelongsToManyAssociation
- Inherits:
-
AssociationCollection
- Object
- AssociationProxy
- AssociationCollection
- ActiveRecord::Associations::HasAndBelongsToManyAssociation
- Defined in:
- lib/active_record/associations/has_and_belongs_to_many_association.rb
Overview
:nodoc:
Instance Method Summary collapse
- #build(attributes = {}) ⇒ Object
-
#clear ⇒ Object
Removes all records from this association.
- #find(*args) ⇒ Object
- #find_first ⇒ Object
-
#initialize(owner, association_name, association_class_name, association_class_primary_key_name, options) ⇒ HasAndBelongsToManyAssociation
constructor
A new instance of HasAndBelongsToManyAssociation.
- #push_with_attributes(record, join_attributes = {}) ⇒ Object (also: #concat_with_attributes)
- #size ⇒ Object
Methods inherited from AssociationCollection
#<<, #create, #delete, #destroy_all, #empty?, #length, #replace, #reset, #to_ary, #uniq
Methods inherited from AssociationProxy
#loaded?, #method_missing, #proxy_respond_to?, #reload, #respond_to?
Constructor Details
#initialize(owner, association_name, association_class_name, association_class_primary_key_name, options) ⇒ HasAndBelongsToManyAssociation
Returns a new instance of HasAndBelongsToManyAssociation.
4 5 6 7 8 9 10 11 12 13 |
# File 'lib/active_record/associations/has_and_belongs_to_many_association.rb', line 4 def initialize(owner, association_name, association_class_name, association_class_primary_key_name, ) super @association_foreign_key = [:association_foreign_key] || Inflector.underscore(Inflector.demodulize(association_class_name)) + "_id" @association_table_name = [:table_name] || @association_class.table_name @join_table = [:join_table] @order = [:order] || "t.#{@association_class.primary_key}" construct_sql end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method in the class ActiveRecord::Associations::AssociationProxy
Instance Method Details
#build(attributes = {}) ⇒ Object
15 16 17 18 19 20 |
# File 'lib/active_record/associations/has_and_belongs_to_many_association.rb', line 15 def build(attributes = {}) load_target record = @association_class.new(attributes) @target << record record end |
#clear ⇒ Object
Removes all records from this association. Returns self
so method calls may be chained.
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/active_record/associations/has_and_belongs_to_many_association.rb', line 23 def clear return self if size == 0 # forces load_target if hasn't happened already if sql = @options[:delete_sql] each { |record| @owner.connection.execute(sql) } elsif @options[:conditions] sql = "DELETE FROM #{@join_table} WHERE #{@association_class_primary_key_name} = #{@owner.quoted_id} " + "AND #{@association_foreign_key} IN (#{collect { |record| record.id }.join(", ")})" @owner.connection.execute(sql) else sql = "DELETE FROM #{@join_table} WHERE #{@association_class_primary_key_name} = #{@owner.quoted_id}" @owner.connection.execute(sql) end @target = [] self end |
#find(*args) ⇒ Object
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/active_record/associations/has_and_belongs_to_many_association.rb', line 46 def find(*args) # Return an Array if multiple ids are given. expects_array = args.first.kind_of?(Array) ids = args.flatten.compact.uniq # If no block is given, raise RecordNotFound. if ids.empty? raise RecordNotFound, "Couldn't find #{@association_class.name} without an ID#{conditions}" # If using a custom finder_sql, scan the entire collection. elsif @options[:finder_sql] if ids.size == 1 id = ids.first record = load_target.detect { |record| id == record.id } expects_array? ? [record] : record else load_target.select { |record| ids.include?(record.id) } end # Otherwise, construct a query. else ids_list = ids.map { |id| @owner.send(:quote, id) }.join(',') records = find_target(@finder_sql.sub(/ORDER BY/, "AND j.#{@association_foreign_key} IN (#{ids_list}) ORDER BY")) if records.size == ids.size if ids.size == 1 and !expects_array records.first else records end else raise RecordNotFound, "Couldn't find #{@association_class.name} with ID in (#{ids_list})" end end end |
#find_first ⇒ Object
42 43 44 |
# File 'lib/active_record/associations/has_and_belongs_to_many_association.rb', line 42 def find_first load_target.first end |
#push_with_attributes(record, join_attributes = {}) ⇒ Object Also known as: concat_with_attributes
82 83 84 85 86 87 88 |
# File 'lib/active_record/associations/has_and_belongs_to_many_association.rb', line 82 def push_with_attributes(record, join_attributes = {}) raise_on_type_mismatch(record) insert_record_with_join_attributes(record, join_attributes) join_attributes.each { |key, value| record.send(:write_attribute, key, value) } @target << record self end |
#size ⇒ Object
92 93 94 |
# File 'lib/active_record/associations/has_and_belongs_to_many_association.rb', line 92 def size @options[:uniq] ? count_records : super end |