Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 122 lines (104 sloc) 4.798 kB
db045db @dhh Initial
dhh authored
1 module ActiveRecord
2 module Associations
3 class HasAndBelongsToManyAssociation < AssociationCollection #:nodoc:
06075a9 @technoweenie Fix the has_and_belongs_to_many #create doesn't populate the join for…
technoweenie authored
4 def create(attributes = {})
a72c1ec @jeremy Refactor association create and build so before & after callbacks beh…
jeremy authored
5 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
6 end
4979448 @technoweenie Ensure that modifying has_and_belongs_to_many actions clear the query…
technoweenie authored
7
7010ee3 @NZKoz Stop users from calling .create on a has_many / habtm association whe…
NZKoz authored
8 def create!(attributes = {})
a72c1ec @jeremy Refactor association create and build so before & after callbacks beh…
jeremy authored
9 create_record(attributes) { |record| insert_record(record, true) }
7010ee3 @NZKoz Stop users from calling .create on a has_many / habtm association whe…
NZKoz authored
10 end
06075a9 @technoweenie Fix the has_and_belongs_to_many #create doesn't populate the join for…
technoweenie authored
11
3ee4e00 @lukeludwig Cache columns for has_and_belongs_to_many associations
lukeludwig authored
12 def columns
13 @reflection.columns(@reflection.options[:join_table], "#{@reflection.options[:join_table]} Columns")
14 end
15
16 def reset_column_information
17 @reflection.reset_column_information
18 end
19
3b6a9a0 @jeremy Revert "Assert primary key does not exist in habtm when the associati…
jeremy authored
20 def has_primary_key?
78790e4 @jeremy Revert "Revert "Assert primary key does not exist in habtm when the a…
jeremy authored
21 @has_primary_key ||= @owner.connection.supports_primary_key? && @owner.connection.primary_key(@reflection.options[:join_table])
3b6a9a0 @jeremy Revert "Assert primary key does not exist in habtm when the associati…
jeremy authored
22 end
23
9bc75fd @lifo Remove duplicate code from associations. [Pratik]
lifo authored
24 protected
25 def construct_find_options!(options)
53aa8da @dhh Fixed that records returned from has_and_belongs_to_many associations…
dhh authored
26 options[:joins] = @join_sql
2e47db2 @dhh Fixed that habtm associations should be able to set :select as part o…
dhh authored
27 options[:readonly] = finding_with_ambiguous_select?(options[:select] || @reflection.options[:select])
9bc75fd @lifo Remove duplicate code from associations. [Pratik]
lifo authored
28 options[:select] ||= (@reflection.options[:select] || '*')
db045db @dhh Initial
dhh authored
29 end
c1f833d @miloops habtm delete method integrated with ARel.
miloops authored
30
db045db @dhh Initial
dhh authored
31 def count_records
823554e @dhh Added support for associating unsaved objects #402 [Tim Bates]
dhh authored
32 load_target.size
db045db @dhh Initial
dhh authored
33 end
34
5cda000 @dhh Fixed that autosave should validate associations even if master is in…
dhh authored
35 def insert_record(record, force = true, validate = true)
85fbb22 @dhh Backed out of new_record? to new? transformation as it would screw up…
dhh authored
36 if record.new_record?
7010ee3 @NZKoz Stop users from calling .create on a has_many / habtm association whe…
NZKoz authored
37 if force
38 record.save!
39 else
5cda000 @dhh Fixed that autosave should validate associations even if master is in…
dhh authored
40 return false unless record.save(validate)
7010ee3 @NZKoz Stop users from calling .create on a has_many / habtm association whe…
NZKoz authored
41 end
a2f26b9 @dhh Fixed that adding a record to a has_and_belongs_to collection would a…
dhh authored
42 end
b29c01e @dhh Added that has_and_belongs_to_many associations with additional attri…
dhh authored
43
6abda69 @dhh Added preliminary support for join models [DHH] Added preliminary sup…
dhh authored
44 if @reflection.options[:insert_sql]
4979448 @technoweenie Ensure that modifying has_and_belongs_to_many actions clear the query…
technoweenie authored
45 @owner.connection.insert(interpolate_sql(@reflection.options[:insert_sql], record))
db045db @dhh Initial
dhh authored
46 else
7b3d85d @jeremy Revert "Split arel_table into method to get a relation and another to…
jeremy authored
47 relation = arel_table(@reflection.options[:join_table])
8b5f4e4 @jeremy Ruby 1.9 compat: fix warnings, shadowed block vars, and unitialized i…
jeremy authored
48 attributes = columns.inject({}) do |attrs, column|
6c1c16b @ddollar Fixes a subtle bug when using symbols for key definitions in habtm as…
ddollar authored
49 case column.name.to_s
50 when @reflection.primary_key_name.to_s
d5476b4 @miloops habtm insertion with ARel integration.
miloops authored
51 attrs[relation[column.name]] = owner_quoted_id
6c1c16b @ddollar Fixes a subtle bug when using symbols for key definitions in habtm as…
ddollar authored
52 when @reflection.association_foreign_key.to_s
d5476b4 @miloops habtm insertion with ARel integration.
miloops authored
53 attrs[relation[column.name]] = record.quoted_id
b29c01e @dhh Added that has_and_belongs_to_many associations with additional attri…
dhh authored
54 else
8b5f4e4 @jeremy Ruby 1.9 compat: fix warnings, shadowed block vars, and unitialized i…
jeremy authored
55 if record.has_attribute?(column.name)
85fbb22 @dhh Backed out of new_record? to new? transformation as it would screw up…
dhh authored
56 value = @owner.send(:quote_value, record[column.name], column)
d5476b4 @miloops habtm insertion with ARel integration.
miloops authored
57 attrs[relation[column.name]] = value unless value.nil?
83e2f6a @jamis Allow unspecified join-table columns to use to their default values w…
jamis authored
58 end
b29c01e @dhh Added that has_and_belongs_to_many associations with additional attri…
dhh authored
59 end
8b5f4e4 @jeremy Ruby 1.9 compat: fix warnings, shadowed block vars, and unitialized i…
jeremy authored
60 attrs
b29c01e @dhh Added that has_and_belongs_to_many associations with additional attri…
dhh authored
61 end
62
d5476b4 @miloops habtm insertion with ARel integration.
miloops authored
63 relation.insert(attributes)
db045db @dhh Initial
dhh authored
64 end
800b899 @jeremy Remove deprecated push_with_attributes.
jeremy authored
65
b29c01e @dhh Added that has_and_belongs_to_many associations with additional attri…
dhh authored
66 return true
db045db @dhh Initial
dhh authored
67 end
800b899 @jeremy Remove deprecated push_with_attributes.
jeremy authored
68
db045db @dhh Initial
dhh authored
69 def delete_records(records)
6abda69 @dhh Added preliminary support for join models [DHH] Added preliminary sup…
dhh authored
70 if sql = @reflection.options[:delete_sql]
4979448 @technoweenie Ensure that modifying has_and_belongs_to_many actions clear the query…
technoweenie authored
71 records.each { |record| @owner.connection.delete(interpolate_sql(sql, record)) }
db045db @dhh Initial
dhh authored
72 else
7b3d85d @jeremy Revert "Split arel_table into method to get a relation and another to…
jeremy authored
73 relation = arel_table(@reflection.options[:join_table])
c1f833d @miloops habtm delete method integrated with ARel.
miloops authored
74 relation.conditions(relation[@reflection.primary_key_name].eq(@owner.id).
e93c2da @jeremy Arel::In -> Arel::Predicates::In
jeremy authored
75 and(Arel::Predicates::In.new(relation[@reflection.association_foreign_key], records.map(&:id)))
c1f833d @miloops habtm delete method integrated with ARel.
miloops authored
76 ).delete
db045db @dhh Initial
dhh authored
77 end
78 end
800b899 @jeremy Remove deprecated push_with_attributes.
jeremy authored
79
823554e @dhh Added support for associating unsaved objects #402 [Tim Bates]
dhh authored
80 def construct_sql
6abda69 @dhh Added preliminary support for join models [DHH] Added preliminary sup…
dhh authored
81 if @reflection.options[:finder_sql]
8cfdcdb @zerowidth Updated has_and_belongs_to_many association to fix :finder_sql interp…
zerowidth authored
82 @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
83 else
0b12da4 @indirect Extract owner_quoted_id so it can be overridden. [#292 state:committed]
indirect authored
84 @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
85 @finder_sql << " AND (#{conditions})" if conditions
71bdf13 @dhh Removed the default order by id on has_and_belongs_to_many queries as…
dhh authored
86 end
d21ba5a @jeremy has_and_belongs_to_many: use JOIN instead of LEFT JOIN. References #…
jeremy authored
87
ebe3a0d @jeremy More thoroughly quote table names. Exposes some issues with sqlite2 a…
jeremy authored
88 @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
89
45e6f19 @lifo Revert "Revert "Generate proper :counter_sql from :finder_sql when th…
lifo authored
90 construct_counter_sql
823554e @dhh Added support for associating unsaved objects #402 [Tim Bates]
dhh authored
91 end
53aa8da @dhh Fixed that records returned from has_and_belongs_to_many associations…
dhh authored
92
02adc49 @jeremy Simplify association proxy implementation by factoring construct_scop…
jeremy authored
93 def construct_scope
440f289 @jeremy Dynamic finders on association collections respect association :limit…
jeremy authored
94 { :find => { :conditions => @finder_sql,
95 :joins => @join_sql,
96 :readonly => false,
97 :order => @reflection.options[:order],
e94e53f @bkeepers fix eager loading with dynamic finders
bkeepers authored
98 :include => @reflection.options[:include],
440f289 @jeremy Dynamic finders on association collections respect association :limit…
jeremy authored
99 :limit => @reflection.options[:limit] } }
02adc49 @jeremy Simplify association proxy implementation by factoring construct_scop…
jeremy authored
100 end
101
e3b49c0 @dhh Fixed spelling errors (closes #9706) [tarmo/rmm5t]
dhh authored
102 # 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
103 # clause has been explicitly defined. Otherwise you can get broken records back, if, for example, the join column also has
104 # 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
105 def finding_with_ambiguous_select?(select_clause)
3ee4e00 @lukeludwig Cache columns for has_and_belongs_to_many associations
lukeludwig authored
106 !select_clause && columns.size != 2
53aa8da @dhh Fixed that records returned from has_and_belongs_to_many associations…
dhh authored
107 end
a72c1ec @jeremy Refactor association create and build so before & after callbacks beh…
jeremy authored
108
109 private
36b8073 @NZKoz Make HABTM#create behave the same as << with after_add callbacks. Cl…
NZKoz authored
110 def create_record(attributes, &block)
a72c1ec @jeremy Refactor association create and build so before & after callbacks beh…
jeremy authored
111 # Can't use Base.create because the foreign key may be a protected attribute.
112 ensure_owner_is_not_new
113 if attributes.is_a?(Array)
114 attributes.collect { |attr| create(attr) }
115 else
36b8073 @NZKoz Make HABTM#create behave the same as << with after_add callbacks. Cl…
NZKoz authored
116 build_record(attributes, &block)
a72c1ec @jeremy Refactor association create and build so before & after callbacks beh…
jeremy authored
117 end
118 end
823554e @dhh Added support for associating unsaved objects #402 [Tim Bates]
dhh authored
119 end
db045db @dhh Initial
dhh authored
120 end
68d1056 @dhh Fixed that has_and_belongs_to_many would generate bad sql when naming…
dhh authored
121 end
Something went wrong with that request. Please try again.