Skip to content
Newer
Older
100644 144 lines (123 sloc) 5.75 KB
db045db @dhh Initial
dhh authored Nov 24, 2004
1 module ActiveRecord
2 module Associations
3 class HasAndBelongsToManyAssociation < AssociationCollection #:nodoc:
2b82708 @jeremy Revert "Assert primary key does not exist in habtm when the associati…
jeremy authored Sep 2, 2009
4 def initialize(owner, reflection)
5 super
6 @primary_key_list = {}
7 end
8
06075a9 @technoweenie Fix the has_and_belongs_to_many #create doesn't populate the join for…
technoweenie authored May 29, 2006
9 def create(attributes = {})
a72c1ec @jeremy Refactor association create and build so before & after callbacks beh…
jeremy authored Oct 16, 2007
10 create_record(attributes) { |record| insert_record(record) }
06075a9 @technoweenie Fix the has_and_belongs_to_many #create doesn't populate the join for…
technoweenie authored May 29, 2006
11 end
4979448 @technoweenie Ensure that modifying has_and_belongs_to_many actions clear the query…
technoweenie authored Jan 18, 2008
12
7010ee3 @NZKoz Stop users from calling .create on a has_many / habtm association whe…
NZKoz authored Sep 18, 2007
13 def create!(attributes = {})
a72c1ec @jeremy Refactor association create and build so before & after callbacks beh…
jeremy authored Oct 16, 2007
14 create_record(attributes) { |record| insert_record(record, true) }
7010ee3 @NZKoz Stop users from calling .create on a has_many / habtm association whe…
NZKoz authored Sep 18, 2007
15 end
06075a9 @technoweenie Fix the has_and_belongs_to_many #create doesn't populate the join for…
technoweenie authored May 29, 2006
16
3ee4e00 Cache columns for has_and_belongs_to_many associations
lukeludwig authored Jan 16, 2009
17 def columns
18 @reflection.columns(@reflection.options[:join_table], "#{@reflection.options[:join_table]} Columns")
19 end
20
21 def reset_column_information
22 @reflection.reset_column_information
23 end
24
2b82708 @jeremy Revert "Assert primary key does not exist in habtm when the associati…
jeremy authored Sep 2, 2009
25 def has_primary_key?
26 return @has_primary_key unless @has_primary_key.nil?
d48d3d0 @sdsykes Fix habtm associations when using multiple databases
sdsykes authored Sep 11, 2009
27 @has_primary_key = (@owner.connection.supports_primary_key? &&
28 @owner.connection.primary_key(@reflection.options[:join_table]))
2b82708 @jeremy Revert "Assert primary key does not exist in habtm when the associati…
jeremy authored Sep 2, 2009
29 end
30
9bc75fd @lifo Remove duplicate code from associations. [Pratik]
lifo authored Apr 6, 2008
31 protected
32 def construct_find_options!(options)
53aa8da @dhh Fixed that records returned from has_and_belongs_to_many associations…
dhh authored Apr 1, 2006
33 options[:joins] = @join_sql
2e47db2 @dhh Fixed that habtm associations should be able to set :select as part o…
dhh authored Dec 5, 2007
34 options[:readonly] = finding_with_ambiguous_select?(options[:select] || @reflection.options[:select])
9bc75fd @lifo Remove duplicate code from associations. [Pratik]
lifo authored Apr 6, 2008
35 options[:select] ||= (@reflection.options[:select] || '*')
db045db @dhh Initial
dhh authored Nov 24, 2004
36 end
9bc75fd @lifo Remove duplicate code from associations. [Pratik]
lifo authored Apr 6, 2008
37
db045db @dhh Initial
dhh authored Nov 24, 2004
38 def count_records
823554e @dhh Added support for associating unsaved objects #402 [Tim Bates]
dhh authored Jan 15, 2005
39 load_target.size
db045db @dhh Initial
dhh authored Nov 24, 2004
40 end
41
5cda000 @dhh Fixed that autosave should validate associations even if master is in…
dhh authored Feb 27, 2009
42 def insert_record(record, force = true, validate = true)
2b82708 @jeremy Revert "Assert primary key does not exist in habtm when the associati…
jeremy authored Sep 2, 2009
43 if has_primary_key?
44 raise ActiveRecord::ConfigurationError,
45 "Primary key is not allowed in a has_and_belongs_to_many join table (#{@reflection.options[:join_table]})."
46 end
47
85fbb22 @dhh Backed out of new_record? to new? transformation as it would screw up…
dhh authored Sep 5, 2006
48 if record.new_record?
7010ee3 @NZKoz Stop users from calling .create on a has_many / habtm association whe…
NZKoz authored Sep 18, 2007
49 if force
50 record.save!
51 else
5cda000 @dhh Fixed that autosave should validate associations even if master is in…
dhh authored Feb 27, 2009
52 return false unless record.save(validate)
7010ee3 @NZKoz Stop users from calling .create on a has_many / habtm association whe…
NZKoz authored Sep 18, 2007
53 end
a2f26b9 @dhh Fixed that adding a record to a has_and_belongs_to collection would a…
dhh authored Jun 18, 2005
54 end
b29c01e @dhh Added that has_and_belongs_to_many associations with additional attri…
dhh authored Jan 24, 2005
55
6abda69 @dhh Added preliminary support for join models [DHH] Added preliminary sup…
dhh authored Dec 3, 2005
56 if @reflection.options[:insert_sql]
4979448 @technoweenie Ensure that modifying has_and_belongs_to_many actions clear the query…
technoweenie authored Jan 18, 2008
57 @owner.connection.insert(interpolate_sql(@reflection.options[:insert_sql], record))
db045db @dhh Initial
dhh authored Nov 24, 2004
58 else
8b5f4e4 @jeremy Ruby 1.9 compat: fix warnings, shadowed block vars, and unitialized i…
jeremy authored Dec 22, 2007
59 attributes = columns.inject({}) do |attrs, column|
6c1c16b @ddollar Fixes a subtle bug when using symbols for key definitions in habtm as…
ddollar authored Apr 13, 2008
60 case column.name.to_s
61 when @reflection.primary_key_name.to_s
0b12da4 @indirect Extract owner_quoted_id so it can be overridden. [#292 state:committed]
indirect authored Jun 4, 2008
62 attrs[column.name] = owner_quoted_id
6c1c16b @ddollar Fixes a subtle bug when using symbols for key definitions in habtm as…
ddollar authored Apr 13, 2008
63 when @reflection.association_foreign_key.to_s
8b5f4e4 @jeremy Ruby 1.9 compat: fix warnings, shadowed block vars, and unitialized i…
jeremy authored Dec 22, 2007
64 attrs[column.name] = record.quoted_id
b29c01e @dhh Added that has_and_belongs_to_many associations with additional attri…
dhh authored Jan 24, 2005
65 else
8b5f4e4 @jeremy Ruby 1.9 compat: fix warnings, shadowed block vars, and unitialized i…
jeremy authored Dec 22, 2007
66 if record.has_attribute?(column.name)
85fbb22 @dhh Backed out of new_record? to new? transformation as it would screw up…
dhh authored Sep 5, 2006
67 value = @owner.send(:quote_value, record[column.name], column)
8b5f4e4 @jeremy Ruby 1.9 compat: fix warnings, shadowed block vars, and unitialized i…
jeremy authored Dec 22, 2007
68 attrs[column.name] = value unless value.nil?
83e2f6a @jamis Allow unspecified join-table columns to use to their default values w…
jamis authored Jul 18, 2005
69 end
b29c01e @dhh Added that has_and_belongs_to_many associations with additional attri…
dhh authored Jan 24, 2005
70 end
8b5f4e4 @jeremy Ruby 1.9 compat: fix warnings, shadowed block vars, and unitialized i…
jeremy authored Dec 22, 2007
71 attrs
b29c01e @dhh Added that has_and_belongs_to_many associations with additional attri…
dhh authored Jan 24, 2005
72 end
73
74 sql =
ebe3a0d @jeremy More thoroughly quote table names. Exposes some issues with sqlite2 a…
jeremy authored Jan 5, 2008
75 "INSERT INTO #{@owner.connection.quote_table_name @reflection.options[:join_table]} (#{@owner.send(:quoted_column_names, attributes).join(', ')}) " +
9870396 @dhh Fixed incompatibility in DB2 adapter with the new limit/offset approach
dhh authored Jul 17, 2005
76 "VALUES (#{attributes.values.join(', ')})"
b29c01e @dhh Added that has_and_belongs_to_many associations with additional attri…
dhh authored Jan 24, 2005
77
4979448 @technoweenie Ensure that modifying has_and_belongs_to_many actions clear the query…
technoweenie authored Jan 18, 2008
78 @owner.connection.insert(sql)
db045db @dhh Initial
dhh authored Nov 24, 2004
79 end
800b899 @jeremy Remove deprecated push_with_attributes.
jeremy authored Jun 11, 2007
80
b29c01e @dhh Added that has_and_belongs_to_many associations with additional attri…
dhh authored Jan 24, 2005
81 return true
db045db @dhh Initial
dhh authored Nov 24, 2004
82 end
800b899 @jeremy Remove deprecated push_with_attributes.
jeremy authored Jun 11, 2007
83
db045db @dhh Initial
dhh authored Nov 24, 2004
84 def delete_records(records)
6abda69 @dhh Added preliminary support for join models [DHH] Added preliminary sup…
dhh authored Dec 3, 2005
85 if sql = @reflection.options[:delete_sql]
4979448 @technoweenie Ensure that modifying has_and_belongs_to_many actions clear the query…
technoweenie authored Jan 18, 2008
86 records.each { |record| @owner.connection.delete(interpolate_sql(sql, record)) }
db045db @dhh Initial
dhh authored Nov 24, 2004
87 else
88 ids = quoted_record_ids(records)
0b12da4 @indirect Extract owner_quoted_id so it can be overridden. [#292 state:committed]
indirect authored Jun 4, 2008
89 sql = "DELETE FROM #{@owner.connection.quote_table_name @reflection.options[:join_table]} WHERE #{@reflection.primary_key_name} = #{owner_quoted_id} AND #{@reflection.association_foreign_key} IN (#{ids})"
4979448 @technoweenie Ensure that modifying has_and_belongs_to_many actions clear the query…
technoweenie authored Jan 18, 2008
90 @owner.connection.delete(sql)
db045db @dhh Initial
dhh authored Nov 24, 2004
91 end
92 end
800b899 @jeremy Remove deprecated push_with_attributes.
jeremy authored Jun 11, 2007
93
823554e @dhh Added support for associating unsaved objects #402 [Tim Bates]
dhh authored Jan 15, 2005
94 def construct_sql
6abda69 @dhh Added preliminary support for join models [DHH] Added preliminary sup…
dhh authored Dec 3, 2005
95 if @reflection.options[:finder_sql]
8cfdcdb @zerowidth Updated has_and_belongs_to_many association to fix :finder_sql interp…
zerowidth authored Aug 16, 2008
96 @finder_sql = interpolate_sql(@reflection.options[:finder_sql])
71bdf13 @dhh Removed the default order by id on has_and_belongs_to_many queries as…
dhh authored Apr 13, 2005
97 else
0b12da4 @indirect Extract owner_quoted_id so it can be overridden. [#292 state:committed]
indirect authored Jun 4, 2008
98 @finder_sql = "#{@owner.connection.quote_table_name @reflection.options[:join_table]}.#{@reflection.primary_key_name} = #{owner_quoted_id} "
a3502c4 @technoweenie Use association's :conditions when eager loading. [jeremyevans0@gmail…
technoweenie authored Mar 16, 2006
99 @finder_sql << " AND (#{conditions})" if conditions
71bdf13 @dhh Removed the default order by id on has_and_belongs_to_many queries as…
dhh authored Apr 13, 2005
100 end
d21ba5a @jeremy has_and_belongs_to_many: use JOIN instead of LEFT JOIN. References #2937
jeremy authored Nov 21, 2005
101
ebe3a0d @jeremy More thoroughly quote table names. Exposes some issues with sqlite2 a…
jeremy authored Jan 5, 2008
102 @join_sql = "INNER JOIN #{@owner.connection.quote_table_name @reflection.options[:join_table]} ON #{@reflection.quoted_table_name}.#{@reflection.klass.primary_key} = #{@owner.connection.quote_table_name @reflection.options[:join_table]}.#{@reflection.association_foreign_key}"
44af2ef @ernie Refactored AssociationCollection#count for uniformity and Ruby 1.8.7 …
ernie authored Aug 28, 2008
103
104 if @reflection.options[:counter_sql]
105 @counter_sql = interpolate_sql(@reflection.options[:counter_sql])
106 elsif @reflection.options[:finder_sql]
107 # replace the SELECT clause with COUNT(*), preserving any hints within /* ... */
108 @reflection.options[:counter_sql] = @reflection.options[:finder_sql].sub(/SELECT (\/\*.*?\*\/ )?(.*)\bFROM\b/im) { "SELECT #{$1}COUNT(*) FROM" }
109 @counter_sql = interpolate_sql(@reflection.options[:counter_sql])
110 else
111 @counter_sql = @finder_sql
112 end
823554e @dhh Added support for associating unsaved objects #402 [Tim Bates]
dhh authored Jan 15, 2005
113 end
53aa8da @dhh Fixed that records returned from has_and_belongs_to_many associations…
dhh authored Apr 1, 2006
114
02adc49 @jeremy Simplify association proxy implementation by factoring construct_scop…
jeremy authored Nov 19, 2006
115 def construct_scope
440f289 @jeremy Dynamic finders on association collections respect association :limit…
jeremy authored Nov 21, 2007
116 { :find => { :conditions => @finder_sql,
117 :joins => @join_sql,
118 :readonly => false,
119 :order => @reflection.options[:order],
e94e53f @bkeepers fix eager loading with dynamic finders
bkeepers authored Jun 9, 2008
120 :include => @reflection.options[:include],
440f289 @jeremy Dynamic finders on association collections respect association :limit…
jeremy authored Nov 21, 2007
121 :limit => @reflection.options[:limit] } }
02adc49 @jeremy Simplify association proxy implementation by factoring construct_scop…
jeremy authored Nov 19, 2006
122 end
123
e3b49c0 @dhh Fixed spelling errors (closes #9706) [tarmo/rmm5t]
dhh authored Sep 28, 2007
124 # Join tables with additional columns on top of the two foreign keys must be considered ambiguous unless a select
18a3333 @NZKoz Formatting, grammar and spelling fixes for the associations documenta…
NZKoz authored Aug 28, 2007
125 # clause has been explicitly defined. Otherwise you can get broken records back, if, for example, the join column also has
126 # an id column. This will then overwrite the id column of the records coming back.
e3b49c0 @dhh Fixed spelling errors (closes #9706) [tarmo/rmm5t]
dhh authored Sep 28, 2007
127 def finding_with_ambiguous_select?(select_clause)
3ee4e00 Cache columns for has_and_belongs_to_many associations
lukeludwig authored Jan 16, 2009
128 !select_clause && columns.size != 2
53aa8da @dhh Fixed that records returned from has_and_belongs_to_many associations…
dhh authored Apr 1, 2006
129 end
a72c1ec @jeremy Refactor association create and build so before & after callbacks beh…
jeremy authored Oct 16, 2007
130
131 private
36b8073 @NZKoz Make HABTM#create behave the same as << with after_add callbacks. Clo…
NZKoz authored Apr 4, 2008
132 def create_record(attributes, &block)
a72c1ec @jeremy Refactor association create and build so before & after callbacks beh…
jeremy authored Oct 16, 2007
133 # Can't use Base.create because the foreign key may be a protected attribute.
134 ensure_owner_is_not_new
135 if attributes.is_a?(Array)
136 attributes.collect { |attr| create(attr) }
137 else
36b8073 @NZKoz Make HABTM#create behave the same as << with after_add callbacks. Clo…
NZKoz authored Apr 4, 2008
138 build_record(attributes, &block)
a72c1ec @jeremy Refactor association create and build so before & after callbacks beh…
jeremy authored Oct 16, 2007
139 end
140 end
823554e @dhh Added support for associating unsaved objects #402 [Tim Bates]
dhh authored Jan 15, 2005
141 end
db045db @dhh Initial
dhh authored Nov 24, 2004
142 end
68d1056 @dhh Fixed that has_and_belongs_to_many would generate bad sql when naming…
dhh authored Dec 14, 2004
143 end
Something went wrong with that request. Please try again.