composite_primary_keys 0.7.5 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Manifest.txt +75 -0
- data/Rakefile +83 -101
- data/lib/composite_primary_keys.rb +8 -0
- data/lib/composite_primary_keys/associations.rb +66 -18
- data/lib/composite_primary_keys/base.rb +169 -159
- data/lib/composite_primary_keys/calculations.rb +63 -0
- data/lib/composite_primary_keys/connection_adapters/postgresql_adapter.rb +11 -0
- data/lib/composite_primary_keys/version.rb +2 -2
- data/scripts/txt2html +4 -2
- data/scripts/txt2js +3 -2
- data/test/abstract_unit.rb +9 -2
- data/test/connections/native_mysql/connection.rb +5 -2
- data/test/connections/native_postgresql/connection.rb +15 -0
- data/test/connections/native_sqlite/connection.rb +10 -0
- data/test/fixtures/db_definitions/mysql.sql +20 -0
- data/test/fixtures/db_definitions/postgresql.sql +100 -0
- data/test/fixtures/db_definitions/sqlite.sql +84 -0
- data/test/fixtures/group.rb +3 -0
- data/test/fixtures/groups.yml +3 -0
- data/test/fixtures/membership.rb +7 -0
- data/test/fixtures/membership_status.rb +3 -0
- data/test/fixtures/membership_statuses.yml +8 -0
- data/test/fixtures/memberships.yml +6 -0
- data/test/{associations_test.rb → test_associations.rb} +22 -12
- data/test/{attributes_test.rb → test_attributes.rb} +4 -5
- data/test/{clone_test.rb → test_clone.rb} +2 -3
- data/test/{create_test.rb → test_create.rb} +2 -3
- data/test/{delete_test.rb → test_delete.rb} +2 -3
- data/test/{dummy_test.rb → test_dummy.rb} +4 -5
- data/test/{find_test.rb → test_find.rb} +3 -4
- data/test/{ids_test.rb → test_ids.rb} +4 -4
- data/test/{miscellaneous_test.rb → test_miscellaneous.rb} +2 -3
- data/test/{pagination_test.rb → test_pagination.rb} +4 -3
- data/test/{santiago_test.rb → test_santiago.rb} +5 -3
- data/test/test_tutorial_examle.rb +29 -0
- data/test/{update_test.rb → test_update.rb} +2 -3
- data/website/index.html +267 -201
- data/website/index.txt +74 -70
- data/website/stylesheets/screen.css +33 -3
- data/website/version-raw.js +1 -1
- data/website/version.js +1 -1
- metadata +80 -66
- data/scripts/http-access2-2.0.6.gem +0 -0
- data/scripts/rubyforge +0 -217
- data/scripts/rubyforge-orig +0 -217
- data/test/fixtures/db_definitions/mysql.drop.sql +0 -10
data/Manifest.txt
ADDED
@@ -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
|
-
|
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
|
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
|
-
%
|
41
|
-
%
|
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
|
-
%
|
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
|
-
%
|
55
|
-
%
|
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
|
-
%
|
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
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
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
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
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
|
-
|
122
|
-
|
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
|
-
|
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
|
-
|
177
|
-
|
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
|
-
|
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
|
-
|
184
|
-
|
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 =
|
263
|
-
|
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
|
342
|
+
"INNER JOIN %s ON %s %s #{@reflection.options[:joins]} #{custom_joins}" % [
|
302
343
|
@reflection.through_reflection.table_name,
|
303
|
-
|
304
|
-
|
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
|
315
|
-
|
316
|
-
|
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
|
|