composite_primary_keys 0.7.5 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/Manifest.txt +75 -0
  2. data/Rakefile +83 -101
  3. data/lib/composite_primary_keys.rb +8 -0
  4. data/lib/composite_primary_keys/associations.rb +66 -18
  5. data/lib/composite_primary_keys/base.rb +169 -159
  6. data/lib/composite_primary_keys/calculations.rb +63 -0
  7. data/lib/composite_primary_keys/connection_adapters/postgresql_adapter.rb +11 -0
  8. data/lib/composite_primary_keys/version.rb +2 -2
  9. data/scripts/txt2html +4 -2
  10. data/scripts/txt2js +3 -2
  11. data/test/abstract_unit.rb +9 -2
  12. data/test/connections/native_mysql/connection.rb +5 -2
  13. data/test/connections/native_postgresql/connection.rb +15 -0
  14. data/test/connections/native_sqlite/connection.rb +10 -0
  15. data/test/fixtures/db_definitions/mysql.sql +20 -0
  16. data/test/fixtures/db_definitions/postgresql.sql +100 -0
  17. data/test/fixtures/db_definitions/sqlite.sql +84 -0
  18. data/test/fixtures/group.rb +3 -0
  19. data/test/fixtures/groups.yml +3 -0
  20. data/test/fixtures/membership.rb +7 -0
  21. data/test/fixtures/membership_status.rb +3 -0
  22. data/test/fixtures/membership_statuses.yml +8 -0
  23. data/test/fixtures/memberships.yml +6 -0
  24. data/test/{associations_test.rb → test_associations.rb} +22 -12
  25. data/test/{attributes_test.rb → test_attributes.rb} +4 -5
  26. data/test/{clone_test.rb → test_clone.rb} +2 -3
  27. data/test/{create_test.rb → test_create.rb} +2 -3
  28. data/test/{delete_test.rb → test_delete.rb} +2 -3
  29. data/test/{dummy_test.rb → test_dummy.rb} +4 -5
  30. data/test/{find_test.rb → test_find.rb} +3 -4
  31. data/test/{ids_test.rb → test_ids.rb} +4 -4
  32. data/test/{miscellaneous_test.rb → test_miscellaneous.rb} +2 -3
  33. data/test/{pagination_test.rb → test_pagination.rb} +4 -3
  34. data/test/{santiago_test.rb → test_santiago.rb} +5 -3
  35. data/test/test_tutorial_examle.rb +29 -0
  36. data/test/{update_test.rb → test_update.rb} +2 -3
  37. data/website/index.html +267 -201
  38. data/website/index.txt +74 -70
  39. data/website/stylesheets/screen.css +33 -3
  40. data/website/version-raw.js +1 -1
  41. data/website/version.js +1 -1
  42. metadata +80 -66
  43. data/scripts/http-access2-2.0.6.gem +0 -0
  44. data/scripts/rubyforge +0 -217
  45. data/scripts/rubyforge-orig +0 -217
  46. data/test/fixtures/db_definitions/mysql.drop.sql +0 -10
@@ -0,0 +1,75 @@
1
+ CHANGELOG
2
+ Manifest.txt
3
+ README
4
+ Rakefile
5
+ install.rb
6
+ lib/composite_primary_keys.rb
7
+ lib/composite_primary_keys/associations.rb
8
+ lib/composite_primary_keys/base.rb
9
+ lib/composite_primary_keys/calculations.rb
10
+ lib/composite_primary_keys/composite_arrays.rb
11
+ lib/composite_primary_keys/connection_adapters/postgresql_adapter.rb
12
+ lib/composite_primary_keys/fixtures.rb
13
+ lib/composite_primary_keys/reflection.rb
14
+ lib/composite_primary_keys/version.rb
15
+ scripts/txt2html
16
+ scripts/txt2js
17
+ test/abstract_unit.rb
18
+ test/composite_arrays_test.rb
19
+ test/connections/native_mysql/connection.rb
20
+ test/connections/native_oracle/connection.rb
21
+ test/connections/native_postgresql/connection.rb
22
+ test/connections/native_sqlite/connection.rb
23
+ test/fixtures/article.rb
24
+ test/fixtures/articles.yml
25
+ test/fixtures/db_definitions/mysql.sql
26
+ test/fixtures/db_definitions/postgresql.sql
27
+ test/fixtures/db_definitions/sqlite.sql
28
+ test/fixtures/group.rb
29
+ test/fixtures/groups.yml
30
+ test/fixtures/membership.rb
31
+ test/fixtures/membership_status.rb
32
+ test/fixtures/membership_statuses.yml
33
+ test/fixtures/memberships.yml
34
+ test/fixtures/product.rb
35
+ test/fixtures/product_tariff.rb
36
+ test/fixtures/product_tariffs.yml
37
+ test/fixtures/products.yml
38
+ test/fixtures/reading.rb
39
+ test/fixtures/readings.yml
40
+ test/fixtures/reference_code.rb
41
+ test/fixtures/reference_codes.yml
42
+ test/fixtures/reference_type.rb
43
+ test/fixtures/reference_types.yml
44
+ test/fixtures/street.rb
45
+ test/fixtures/streets.yml
46
+ test/fixtures/suburb.rb
47
+ test/fixtures/suburbs.yml
48
+ test/fixtures/tariff.rb
49
+ test/fixtures/tariffs.yml
50
+ test/fixtures/user.rb
51
+ test/fixtures/users.yml
52
+ test/hash_tricks.rb
53
+ test/test_associations.rb
54
+ test/test_attributes.rb
55
+ test/test_clone.rb
56
+ test/test_create.rb
57
+ test/test_delete.rb
58
+ test/test_dummy.rb
59
+ test/test_find.rb
60
+ test/test_ids.rb
61
+ test/test_miscellaneous.rb
62
+ test/test_pagination.rb
63
+ test/test_santiago.rb
64
+ test/test_tutorial_examle.rb
65
+ test/test_update.rb
66
+ website/index.html
67
+ website/index.txt
68
+ website/javascripts/rounded_corners_lite.inc.js
69
+ website/stylesheets/screen.css
70
+ website/template.js
71
+ website/template.rhtml
72
+ website/version-raw.js
73
+ website/version-raw.txt
74
+ website/version.js
75
+ website/version.txt
data/Rakefile CHANGED
@@ -1,12 +1,56 @@
1
1
  require 'rubygems'
2
2
  require 'rake'
3
+ require 'rake/clean'
3
4
  require 'rake/testtask'
4
5
  require 'rake/rdoctask'
5
6
  require 'rake/packagetask'
6
7
  require 'rake/gempackagetask'
7
8
  require 'rake/contrib/rubyforgepublisher'
9
+ require 'fileutils'
10
+ require 'hoe'
11
+ include FileUtils
8
12
  require File.join(File.dirname(__FILE__), 'lib', 'composite_primary_keys', 'version')
9
13
 
14
+ AUTHOR = "Dr Nic Williams"
15
+ EMAIL = "drnicwilliams@gmail.com"
16
+ DESCRIPTION = "Composite key support for ActiveRecords"
17
+ GEM_NAME = "composite_primary_keys" # what ppl will type to install your gem
18
+ RUBYFORGE_PROJECT = "compositekeys"
19
+ HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
20
+
21
+ REV = nil #File.read(".svn/entries")[/committed-rev="(\d+)"/, 1] rescue nil
22
+ VERSION = ENV['VERSION'] || (CompositePrimaryKeys::VERSION::STRING + (REV ? ".#{REV}" : ""))
23
+ CLEAN.include ['**/.*.sw?', '*.gem', '.config']
24
+ RDOC_OPTS = ['--quiet', '--title', "newgem documentation",
25
+ "--opname", "index.html",
26
+ "--line-numbers",
27
+ "--main", "README",
28
+ "--inline-source"]
29
+
30
+ class Hoe
31
+ def extra_deps
32
+ @extra_deps.reject { |x| Array(x).first == 'hoe' }
33
+ end
34
+ end
35
+
36
+ # Generate all the Rake tasks
37
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
38
+ hoe = Hoe.new(GEM_NAME, VERSION) do |p|
39
+ p.author = AUTHOR
40
+ p.description = DESCRIPTION
41
+ p.email = EMAIL
42
+ p.summary = DESCRIPTION
43
+ p.url = HOMEPATH
44
+ p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
45
+ p.test_globs = ["test/**/test*.rb"]
46
+ p.clean_globs = CLEAN #An array of file patterns to delete on clean.
47
+
48
+ # == Optional
49
+ #p.changes - A description of the release's latest changes.
50
+ p.extra_deps = [['activerecord', '>= 1.14.3']] #An array of rubygem dependencies.
51
+ #p.spec_extras - A hash of extra values to set in the gemspec.
52
+ end
53
+
10
54
  PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
11
55
  PKG_NAME = 'composite_primary_keys'
12
56
  PKG_VERSION = CompositePrimaryKeys::VERSION::STRING + PKG_BUILD
@@ -18,16 +62,10 @@ RUBY_FORGE_PROJECT = "compositekeys"
18
62
  RUBY_FORGE_USER = "nicwilliams"
19
63
 
20
64
 
21
- desc "Default Task"
22
- task :default => [ :test_mysql ] # UNTESTED =, :test_sqlite, :test_postgresql ]
23
- task :test => [ :test_mysql ]
24
-
25
- # Run the unit tests
26
-
27
- for adapter in %w( mysql ) # UNTESTED - postgresql sqlite sqlite3 firebird sqlserver sqlserver_odbc db2 oracle sybase openbase )
65
+ for adapter in %w( mysql sqlite oracle postgresql ) # UNTESTED - firebird sqlserver sqlserver_odbc db2 sybase openbase )
28
66
  Rake::TestTask.new("test_#{adapter}") { |t|
29
67
  t.libs << "test" << "test/connections/native_#{adapter}"
30
- t.pattern = "test/*_test{,_#{adapter}}.rb"
68
+ t.pattern = "test/test_*.rb"
31
69
  t.verbose = true
32
70
  }
33
71
  end
@@ -37,121 +75,65 @@ SCHEMA_PATH = File.join(File.dirname(__FILE__), *%w(test fixtures db_definitions
37
75
  desc 'Build the MySQL test databases'
38
76
  task :build_mysql_databases do
39
77
  puts File.join(SCHEMA_PATH, 'mysql.sql')
40
- %x( mysqladmin -u root create "#{PKG_NAME}_unittest" )
41
- %x( mysql -u root "#{PKG_NAME}_unittest" < #{File.join(SCHEMA_PATH, 'mysql.sql')} )
78
+ sh %{ mysqladmin -u root create "#{PKG_NAME}_unittest" }
79
+ sh %{ mysql -u root "#{PKG_NAME}_unittest" < #{File.join(SCHEMA_PATH, 'mysql.sql')} }
42
80
  end
43
81
 
44
82
  desc 'Drop the MySQL test databases'
45
83
  task :drop_mysql_databases do
46
- %x( mysqladmin -u root -f drop "#{PKG_NAME}_unittest" )
84
+ sh %{ mysqladmin -u root -f drop "#{PKG_NAME}_unittest" }
47
85
  end
48
86
 
49
87
  desc 'Rebuild the MySQL test databases'
88
+
50
89
  task :rebuild_mysql_databases => [:drop_mysql_databases, :build_mysql_databases]
51
90
 
91
+ desc 'Build the sqlite test databases'
92
+ task :build_sqlite_databases do
93
+ file = File.join(SCHEMA_PATH, 'sqlite.sql')
94
+ cmd = "sqlite3 test.db < #{file}"
95
+ puts cmd
96
+ sh %{ #{cmd} }
97
+ end
98
+
99
+ desc 'Drop the sqlite test databases'
100
+ task :drop_sqlite_databases do
101
+ sh %{ rm -f test.db }
102
+ end
103
+
104
+ desc 'Rebuild the sqlite test databases'
105
+ task :rebuild_sqlite_databases => [:drop_sqlite_databases, :build_sqlite_databases]
106
+
52
107
  desc 'Build the PostgreSQL test databases'
53
108
  task :build_postgresql_databases do
54
- %x( createdb "#{PKG_NAME}_unittest" )
55
- %x( psql "#{PKG_NAME}_unittest" -f #{File.join(SCHEMA_PATH, 'postgresql.sql')} )
109
+ sh %{ createdb "#{PKG_NAME}_unittest" }
110
+ sh %{ psql "#{PKG_NAME}_unittest" -f #{File.join(SCHEMA_PATH, 'postgresql.sql')} }
56
111
  end
57
112
 
58
113
  desc 'Drop the PostgreSQL test databases'
59
114
  task :drop_postgresql_databases do
60
- %x( dropdb "#{PKG_NAME}_unittest" )
115
+ sh %{ dropdb "#{PKG_NAME}_unittest" }
61
116
  end
62
117
 
63
118
  desc 'Rebuild the PostgreSQL test databases'
64
119
  task :rebuild_postgresql_databases => [:drop_postgresql_databases, :build_postgresql_databases]
65
120
 
66
- # Generate the RDoc documentation
67
-
68
- Rake::RDocTask.new { |rdoc|
69
- rdoc.rdoc_dir = 'doc'
70
- rdoc.title = "Composite Primary Keys -- Composite keys for Active Records/Rails"
71
- rdoc.options << '--line-numbers' << '--inline-source' << '-A cattr_accessor=object'
72
- rdoc.template = "#{ENV['template']}.rb" if ENV['template']
73
- rdoc.rdoc_files.include('README', 'CHANGELOG')
74
- rdoc.rdoc_files.include('lib/**/*.rb')
75
- rdoc.rdoc_files.exclude('lib/active_record/vendor/*')
76
- rdoc.rdoc_files.include('dev-utils/*.rb')
77
- }
78
-
79
- # Enhance rdoc task to copy referenced images also
80
- task :rdoc do
81
- FileUtils.mkdir_p "doc/files/examples/"
121
+ desc 'Generate website files'
122
+ task :website_generate do
123
+ sh %{ ruby scripts/txt2html website/index.txt > website/index.html }
124
+ sh %{ ruby scripts/txt2js website/version.txt > website/version.js }
125
+ sh %{ ruby scripts/txt2js website/version-raw.txt > website/version-raw.js }
82
126
  end
83
127
 
84
-
85
- # Create compressed packages
86
-
87
- dist_dirs = [ "lib", "test", "website", "scripts" ]
88
-
89
- spec = Gem::Specification.new do |s|
90
- s.name = PKG_NAME
91
- s.version = PKG_VERSION
92
- s.summary = "Support for composite primary keys in ActiveRecords"
93
- s.description = %q{ActiveRecords only support a single primary key, preventing their use on legacy databases where tables have primary keys over 2+ columns. This solution allows an ActiveRecord to be extended to support multiple keys using the class method set_primary_keys.}
94
-
95
- s.files = [ "Rakefile", "install.rb", "README", "CHANGELOG" ]
96
- dist_dirs.each do |dir|
97
- s.files = s.files + Dir.glob( "#{dir}/**/*" ).delete_if { |item| item.include?( "\.svn" ) }
98
- end
99
-
100
- s.add_dependency('activerecord', '>= 1.14.3' + PKG_BUILD)
101
-
102
- s.require_path = 'lib'
103
- s.autorequire = 'composite_primary_keys'
104
-
105
- s.has_rdoc = true
106
- s.extra_rdoc_files = %w( README )
107
- s.rdoc_options.concat ['--main', 'README']
108
-
109
- s.author = "Dr Nic Williams"
110
- s.email = "drnicwilliams@gmail.com"
111
- s.homepage = "http://compositekeys.rubyforge.org"
112
- s.rubyforge_project = "compositekeys"
113
- end
114
-
115
- Rake::GemPackageTask.new(spec) do |p|
116
- p.gem_spec = spec
117
- p.need_tar = false
118
- p.need_zip = false
128
+ desc 'Upload website files to rubyforge'
129
+ task :website_upload do
130
+ config = YAML.load(File.read(File.expand_path("~/.rubyforge/user-config.yml")))
131
+ host = "#{config["username"]}@rubyforge.org"
132
+ remote_dir = "/var/www/gforge-projects/#{RUBYFORGE_PROJECT}/"
133
+ local_dir = 'website'
134
+ sh %{rsync -av --delete #{local_dir}/ #{host}:#{remote_dir}}
119
135
  end
120
136
 
121
- task :lines do
122
- lines, codelines, total_lines, total_codelines = 0, 0, 0, 0
123
-
124
- for file_name in FileList["lib/composite_primary_keys/**/*.rb"]
125
- next if file_name =~ /vendor/
126
- f = File.open(file_name)
127
-
128
- while line = f.gets
129
- lines += 1
130
- next if line =~ /^\s*$/
131
- next if line =~ /^\s*#/
132
- codelines += 1
133
- end
134
- puts "L: #{sprintf("%4d", lines)}, LOC #{sprintf("%4d", codelines)} | #{file_name}"
135
-
136
- total_lines += lines
137
- total_codelines += codelines
138
-
139
- lines, codelines = 0, 0
140
- end
141
-
142
- puts "Total: Lines #{total_lines}, LOC #{total_codelines}"
137
+ desc 'Generate and upload website files'
138
+ task :website => [:website_generate, :website_upload] do
143
139
  end
144
-
145
-
146
- # Publishing ------------------------------------------------------
147
-
148
- desc "Publish the release files to RubyForge."
149
- task :release => [ :package ] do
150
- `ruby scripts/rubyforge login`
151
-
152
- for ext in %w( gem tgz zip )
153
- release_command = "ruby scripts/rubyforge add_release #{PKG_NAME} #{PKG_NAME} 'REL #{PKG_VERSION}' pkg/#{PKG_NAME}-#{PKG_VERSION}.#{ext}"
154
- puts release_command
155
- system(release_command)
156
- end
157
- end
@@ -39,7 +39,15 @@ require 'composite_primary_keys/composite_arrays'
39
39
  require 'composite_primary_keys/associations'
40
40
  require 'composite_primary_keys/reflection'
41
41
  require 'composite_primary_keys/base'
42
+ require 'composite_primary_keys/calculations'
42
43
 
43
44
  ActiveRecord::Base.class_eval do
44
45
  include CompositePrimaryKeys::ActiveRecord::Base
45
46
  end
47
+
48
+ RAILS_CONNECTION_ADAPTERS.each do |adapter|
49
+ begin
50
+ require "composite_primary_keys/connection_adapters/" + adapter + "_adapter"
51
+ rescue MissingSourceFile
52
+ end
53
+ end
@@ -125,10 +125,12 @@ module ActiveRecord::Associations::ClassMethods
125
125
  def composite_association_join
126
126
  join = case reflection.macro
127
127
  when :has_and_belongs_to_many
128
+ # TODO replace (keys) = (ids), with key1=id1 and key2=id2
128
129
  " LEFT OUTER JOIN %s ON (%s) = (%s) " % [
129
130
  table_alias_for(options[:join_table], aliased_join_table_name),
130
131
  full_keys(aliased_join_table_name, options[:foreign_key] || reflection.active_record.to_s.classify.foreign_key),
131
132
  full_keys(reflection.active_record.table_name, reflection.active_record.primary_key)] +
133
+ # TODO replace (keys) = (ids), with key1=id1 and key2=id2
132
134
  " LEFT OUTER JOIN %s ON (%s) = (%s) " % [
133
135
  table_name_and_alias,
134
136
  full_keys(aliased_table_name, klass.primary_key),
@@ -153,10 +155,12 @@ module ActiveRecord::Associations::ClassMethods
153
155
  second_key = options[:foreign_key] || primary_key
154
156
  end
155
157
 
158
+ # TODO replace (keys) = (ids), with key1=id1 and key2=id2
156
159
  " LEFT OUTER JOIN %s ON (%s) = (%s) " % [
157
160
  table_alias_for(through_reflection.klass.table_name, aliased_join_table_name),
158
161
  full_keys(aliased_join_table_name, through_reflection.primary_key_name),
159
162
  full_keys(parent.aliased_table_name, parent.primary_key)] +
163
+ # TODO replace (keys) = (ids), with key1=id1 and key2=id2
160
164
  " LEFT OUTER JOIN %s ON (%s) = (%s) " % [
161
165
  table_name_and_alias,
162
166
  full_keys(aliased_table_name, first_key),
@@ -171,17 +175,21 @@ module ActiveRecord::Associations::ClassMethods
171
175
  raise AssociationNotSupported, "Polymorphic joins not supported for composite keys"
172
176
  else
173
177
  foreign_key = options[:foreign_key] || reflection.active_record.name.foreign_key
174
- " LEFT OUTER JOIN %s ON (%s) = (%s) " % [
178
+ # TODO replace (keys) = (ids), with key1=id1 and key2=id2
179
+ " LEFT OUTER JOIN %s ON %s " % [
175
180
  table_name_and_alias,
176
- full_keys(aliased_table_name, foreign_key),
177
- full_keys(parent.aliased_table_name, parent.primary_key)
181
+ composite_join_clause(
182
+ full_keys(aliased_table_name, foreign_key),
183
+ full_keys(parent.aliased_table_name, parent.primary_key)),
178
184
  ]
179
185
  end
180
186
  when :belongs_to
181
- " LEFT OUTER JOIN %s ON (%s) = (%s) " % [
187
+ # TODO replace (keys) = (ids), with key1=id1 and key2=id2
188
+ " LEFT OUTER JOIN %s ON %s " % [
182
189
  table_name_and_alias,
183
- full_keys(aliased_table_name, reflection.klass.primary_key),
184
- full_keys(parent.aliased_table_name, options[:foreign_key] || klass.to_s.foreign_key)
190
+ composite_join_clause(
191
+ full_keys(aliased_table_name, reflection.klass.primary_key),
192
+ full_keys(parent.aliased_table_name, options[:foreign_key] || klass.to_s.foreign_key)),
185
193
  ]
186
194
  else
187
195
  ""
@@ -197,12 +205,47 @@ module ActiveRecord::Associations::ClassMethods
197
205
  def full_keys(table_name, keys)
198
206
  keys.collect {|key| "#{table_name}.#{key}"}.join(CompositePrimaryKeys::ID_SEP)
199
207
  end
208
+
209
+ def composite_join_clause(full_keys1, full_keys2)
210
+ full_keys1 = full_keys1.split(CompositePrimaryKeys::ID_SEP) if full_keys1.is_a?(String)
211
+ full_keys2 = full_keys2.split(CompositePrimaryKeys::ID_SEP) if full_keys2.is_a?(String)
212
+ where_clause = [full_keys1, full_keys2].transpose.map do |key_pair|
213
+ "#{key_pair.first}=#{key_pair.last}"
214
+ end.join(" AND ")
215
+ "(#{where_clause})"
216
+ end
200
217
  end
201
218
  end
202
219
  end
203
220
 
204
221
  module ActiveRecord::Associations
205
222
  class AssociationProxy #:nodoc:
223
+
224
+ def composite_where_clause(full_keys, ids)
225
+ full_keys = full_keys.split(CompositePrimaryKeys::ID_SEP) if full_keys.is_a?(String)
226
+ if ids.is_a?(String)
227
+ ids = [[ids]]
228
+ elsif not ids.first.is_a?(Array) # if single comp key passed, turn into an array of 1
229
+ ids = [ids.to_composite_ids]
230
+ end
231
+ where_clause = ids.map do |id_set|
232
+ transposed = id_set.size == 1 ? [[full_keys, id_set.first]] : [full_keys, id_set].transpose
233
+ transposed.map do |full_key, id|
234
+ "#{full_key.to_s}=#{@reflection.klass.sanitize(id)}"
235
+ end.join(" AND ")
236
+ end.join(") OR (")
237
+ "(#{where_clause})"
238
+ end
239
+
240
+ def composite_join_clause(full_keys1, full_keys2)
241
+ full_keys1 = full_keys1.split(CompositePrimaryKeys::ID_SEP) if full_keys1.is_a?(String)
242
+ full_keys2 = full_keys2.split(CompositePrimaryKeys::ID_SEP) if full_keys2.is_a?(String)
243
+ where_clause = [full_keys1, full_keys2].transpose.map do |key_pair|
244
+ "#{key_pair.first}=#{key_pair.last}"
245
+ end.join(" AND ")
246
+ "(#{where_clause})"
247
+ end
248
+
206
249
  def full_keys(table_name, keys)
207
250
  keys = keys.split(CompositePrimaryKeys::ID_SEP) if keys.is_a?(String)
208
251
  keys.is_a?(Array) ?
@@ -211,7 +254,7 @@ module ActiveRecord::Associations
211
254
  end
212
255
 
213
256
  def full_columns_equals(table_name, keys, quoted_ids)
214
- if keys.is_a?(Symbol) or (keys.is_a?(String) and keys == keys.split(CompositePrimaryKeys::ID_SEP))
257
+ if keys.is_a?(Symbol) or (keys.is_a?(String) and keys == keys.to_s.split(CompositePrimaryKeys::ID_SEP))
215
258
  return "#{table_name}.#{keys} = #{quoted_ids}"
216
259
  end
217
260
  keys = keys.split(CompositePrimaryKeys::ID_SEP) if keys.is_a?(String)
@@ -259,10 +302,8 @@ module ActiveRecord::Associations
259
302
  "#{@reflection.klass.table_name}.#{@reflection.options[:as]}_id = #{@owner.quoted_id} AND " +
260
303
  "#{@reflection.klass.table_name}.#{@reflection.options[:as]}_type = #{@owner.class.quote @owner.class.base_class.name.to_s}"
261
304
  else
262
- @finder_sql = "(%s) = (%s)" % [
263
- full_keys(@reflection.table_name, @reflection.primary_key_name),
264
- @owner.quoted_id
265
- ]
305
+ @finder_sql = full_columns_equals(@reflection.klass.table_name,
306
+ @reflection.primary_key_name, @owner.quoted_id)
266
307
  end
267
308
  @finder_sql << " AND (#{conditions})" if conditions
268
309
  end
@@ -298,10 +339,11 @@ module ActiveRecord::Associations
298
339
  end
299
340
  end
300
341
 
301
- "INNER JOIN %s ON (%s) = (%s) %s #{@reflection.options[:joins]} #{custom_joins}" % [
342
+ "INNER JOIN %s ON %s %s #{@reflection.options[:joins]} #{custom_joins}" % [
302
343
  @reflection.through_reflection.table_name,
303
- full_keys(@reflection.table_name, reflection_primary_key),
304
- full_keys(@reflection.through_reflection.table_name, source_primary_key),
344
+ composite_join_clause(
345
+ full_keys(@reflection.table_name, reflection_primary_key),
346
+ full_keys(@reflection.through_reflection.table_name, source_primary_key)),
305
347
  polymorphic_join
306
348
  ]
307
349
  end
@@ -311,10 +353,16 @@ module ActiveRecord::Associations
311
353
  when @reflection.options[:finder_sql]
312
354
  @finder_sql = interpolate_sql(@reflection.options[:finder_sql])
313
355
 
314
- @finder_sql = "(%s) = (%s)" % [
315
- full_keys(@reflection.klass.table_name, @reflection.primary_key_name),
316
- @owner.quoted_id
317
- ]
356
+ @finder_sql << " AND (#{conditions})" if conditions
357
+ when @reflection.options[:as]
358
+ @finder_sql =
359
+ "#{@reflection.klass.table_name}.#{@reflection.options[:as]}_id = #{@owner.quoted_id} AND " +
360
+ "#{@reflection.klass.table_name}.#{@reflection.options[:as]}_type = #{@owner.class.quote_value(@owner.class.base_class.name.to_s)}"
361
+ @finder_sql << " AND (#{conditions})" if conditions
362
+
363
+ else
364
+ @finder_sql = composite_where_clause(
365
+ full_keys(@reflection.klass.table_name, @reflection.primary_key_name), @owner.quoted_id),
318
366
  @finder_sql << " AND (#{conditions})" if conditions
319
367
  end
320
368