activerecord 1.15.2 → 1.15.3
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- data/CHANGELOG +11 -0
- data/Rakefile +8 -8
- data/lib/active_record/associations.rb +61 -44
- data/lib/active_record/associations/has_many_through_association.rb +11 -1
- data/lib/active_record/base.rb +8 -9
- data/lib/active_record/fixtures.rb +18 -6
- data/lib/active_record/reflection.rb +6 -2
- data/lib/active_record/vendor/mysql.rb +8 -4
- data/lib/active_record/version.rb +1 -1
- data/test/associations/join_model_test.rb +18 -1
- data/test/fixtures/categories_ordered.yml +1 -1
- data/test/fixtures/db_definitions/db2.drop.sql +1 -0
- data/test/fixtures/db_definitions/db2.sql +5 -0
- data/test/fixtures/db_definitions/firebird.drop.sql +2 -0
- data/test/fixtures/db_definitions/firebird.sql +7 -0
- data/test/fixtures/db_definitions/frontbase.drop.sql +1 -0
- data/test/fixtures/db_definitions/frontbase.sql +6 -0
- data/test/fixtures/db_definitions/mysql.drop.sql +1 -0
- data/test/fixtures/db_definitions/mysql.sql +6 -0
- data/test/fixtures/db_definitions/openbase.sql +8 -0
- data/test/fixtures/db_definitions/oracle.drop.sql +2 -0
- data/test/fixtures/db_definitions/oracle.sql +6 -0
- data/test/fixtures/db_definitions/postgresql.drop.sql +1 -0
- data/test/fixtures/db_definitions/postgresql.sql +5 -0
- data/test/fixtures/db_definitions/sqlite.drop.sql +1 -0
- data/test/fixtures/db_definitions/sqlite.sql +5 -0
- data/test/fixtures/db_definitions/sqlserver.drop.sql +1 -0
- data/test/fixtures/db_definitions/sqlserver.sql +5 -0
- data/test/fixtures/db_definitions/sybase.drop.sql +1 -0
- data/test/fixtures/db_definitions/sybase.sql +5 -0
- data/test/fixtures/mixed_case_monkey.rb +3 -0
- data/test/fixtures/mixed_case_monkeys.yml +6 -0
- data/test/fixtures/tag.rb +2 -0
- data/test/fixtures/vertex.rb +1 -1
- data/test/pk_test.rb +24 -1
- metadata +6 -4
data/CHANGELOG
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
*1.15.3* (March 12th, 2007)
|
2
|
+
|
3
|
+
* Allow a polymorphic :source for has_many :through associations. Closes #7143 [protocool]
|
4
|
+
|
5
|
+
* Consistently quote primary key column names. #7763 [toolmantim]
|
6
|
+
|
7
|
+
* Fixtures: fix YAML ordered map support. #2665 [Manuel Holtgrewe, nfbuckley]
|
8
|
+
|
9
|
+
* Fix has_many :through << with custom foreign keys. #6466, #7153 [naffis, Rich Collins]
|
10
|
+
|
11
|
+
|
1
12
|
*1.15.2* (February 5th, 2007)
|
2
13
|
|
3
14
|
* Pass a range in :conditions to use the SQL BETWEEN operator. #6974 [dcmanges]
|
data/Rakefile
CHANGED
@@ -151,7 +151,7 @@ spec = Gem::Specification.new do |s|
|
|
151
151
|
s.files = s.files + Dir.glob( "#{dir}/**/*" ).delete_if { |item| item.include?( "\.svn" ) }
|
152
152
|
end
|
153
153
|
|
154
|
-
s.add_dependency('activesupport', '= 1.4.
|
154
|
+
s.add_dependency('activesupport', '= 1.4.2' + PKG_BUILD)
|
155
155
|
|
156
156
|
s.files.delete "test/fixtures/fixture_database.sqlite"
|
157
157
|
s.files.delete "test/fixtures/fixture_database_2.sqlite"
|
@@ -216,11 +216,11 @@ end
|
|
216
216
|
|
217
217
|
desc "Publish the release files to RubyForge."
|
218
218
|
task :release => [ :package ] do
|
219
|
-
|
219
|
+
require 'rubyforge'
|
220
220
|
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
end
|
221
|
+
packages = %w( gem tgz zip ).collect{ |ext| "pkg/#{PKG_NAME}-#{PKG_VERSION}.#{ext}" }
|
222
|
+
|
223
|
+
rubyforge = RubyForge.new
|
224
|
+
rubyforge.login
|
225
|
+
rubyforge.add_release(PKG_NAME, PKG_NAME, "REL #{PKG_VERSION}", *packages)
|
226
|
+
end
|
@@ -20,7 +20,13 @@ module ActiveRecord
|
|
20
20
|
super("Cannot have a has_many :through association '#{owner_class_name}##{reflection.name}' on the polymorphic object '#{source_reflection.class_name}##{source_reflection.name}'.")
|
21
21
|
end
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
|
+
class HasManyThroughAssociationPointlessSourceTypeError < ActiveRecordError #:nodoc:
|
25
|
+
def initialize(owner_class_name, reflection, source_reflection)
|
26
|
+
super("Cannot have a has_many :through association '#{owner_class_name}##{reflection.name}' with a :source_type option if the '#{reflection.through_reflection.class_name}##{source_reflection.name}' is not polymorphic. Try removing :source_type on your association.")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
24
30
|
class HasManyThroughSourceAssociationNotFoundError < ActiveRecordError #:nodoc:
|
25
31
|
def initialize(reflection)
|
26
32
|
through_reflection = reflection.through_reflection
|
@@ -529,6 +535,8 @@ module ActiveRecord
|
|
529
535
|
# * <tt>:source</tt>: Specifies the source association name used by <tt>has_many :through</tt> queries. Only use it if the name cannot be
|
530
536
|
# inferred from the association. <tt>has_many :subscribers, :through => :subscriptions</tt> will look for either +:subscribers+ or
|
531
537
|
# +:subscriber+ on +Subscription+, unless a +:source+ is given.
|
538
|
+
# * <tt>:source_type</tt>: Specifies type of the source association used by <tt>has_many :through</tt> queries where the source association
|
539
|
+
# is a polymorphic belongs_to.
|
532
540
|
# * <tt>:uniq</tt> - if set to true, duplicates will be omitted from the collection. Useful in conjunction with :through.
|
533
541
|
#
|
534
542
|
# Option examples:
|
@@ -1087,7 +1095,7 @@ module ActiveRecord
|
|
1087
1095
|
:class_name, :table_name, :foreign_key,
|
1088
1096
|
:exclusively_dependent, :dependent,
|
1089
1097
|
:select, :conditions, :include, :order, :group, :limit, :offset,
|
1090
|
-
:as, :through, :source,
|
1098
|
+
:as, :through, :source, :source_type,
|
1091
1099
|
:uniq,
|
1092
1100
|
:finder_sql, :counter_sql,
|
1093
1101
|
:before_add, :after_add, :before_remove, :after_remove,
|
@@ -1491,57 +1499,65 @@ module ActiveRecord
|
|
1491
1499
|
case
|
1492
1500
|
when reflection.macro == :has_many && reflection.options[:through]
|
1493
1501
|
through_conditions = through_reflection.options[:conditions] ? "AND #{interpolate_sql(sanitize_sql(through_reflection.options[:conditions]))}" : ''
|
1502
|
+
|
1503
|
+
jt_foreign_key = jt_as_extra = jt_source_extra = jt_sti_extra = nil
|
1504
|
+
first_key = second_key = as_extra = nil
|
1505
|
+
|
1494
1506
|
if through_reflection.options[:as] # has_many :through against a polymorphic join
|
1495
|
-
|
1496
|
-
|
1497
|
-
|
1498
|
-
|
1499
|
-
table_alias_for(through_reflection.klass.table_name, aliased_join_table_name),
|
1500
|
-
aliased_join_table_name, polymorphic_foreign_key,
|
1501
|
-
parent.aliased_table_name, parent.primary_key,
|
1502
|
-
aliased_join_table_name, polymorphic_foreign_type, klass.quote_value(parent.active_record.base_class.name)] +
|
1503
|
-
" LEFT OUTER JOIN %s ON %s.%s = %s.%s " % [table_name_and_alias,
|
1504
|
-
aliased_table_name, primary_key, aliased_join_table_name, options[:foreign_key] || reflection.klass.to_s.classify.foreign_key
|
1507
|
+
jt_foreign_key = through_reflection.options[:as].to_s + '_id'
|
1508
|
+
jt_as_extra = " AND %s.%s = %s" % [
|
1509
|
+
aliased_join_table_name, reflection.active_record.connection.quote_column_name(through_reflection.options[:as].to_s + '_type'),
|
1510
|
+
klass.quote_value(parent.active_record.base_class.name)
|
1505
1511
|
]
|
1506
1512
|
else
|
1507
|
-
|
1508
|
-
|
1509
|
-
|
1510
|
-
|
1511
|
-
|
1512
|
-
|
1513
|
-
|
1514
|
-
|
1515
|
-
|
1516
|
-
aliased_table_name, "#{source_reflection.options[:as]}_type",
|
1513
|
+
jt_foreign_key = through_reflection.primary_key_name
|
1514
|
+
end
|
1515
|
+
|
1516
|
+
case source_reflection.macro
|
1517
|
+
when :has_many
|
1518
|
+
if source_reflection.options[:as]
|
1519
|
+
first_key = "#{source_reflection.options[:as]}_id"
|
1520
|
+
second_key = options[:foreign_key] || primary_key
|
1521
|
+
as_extra = " AND %s.%s = %s" % [
|
1522
|
+
aliased_table_name, reflection.active_record.connection.quote_column_name("#{source_reflection.options[:as]}_type"),
|
1517
1523
|
klass.quote_value(source_reflection.active_record.base_class.name)
|
1518
1524
|
]
|
1519
1525
|
else
|
1520
|
-
|
1521
|
-
|
1522
|
-
|
1523
|
-
|
1524
|
-
|
1525
|
-
|
1526
|
-
|
1527
|
-
|
1528
|
-
|
1529
|
-
|
1530
|
-
|
1531
|
-
|
1532
|
-
|
1533
|
-
|
1534
|
-
|
1535
|
-
|
1536
|
-
|
1537
|
-
parent.aliased_table_name, parent.primary_key, extra] +
|
1538
|
-
" LEFT OUTER JOIN %s ON (%s.%s = %s.%s) " % [
|
1539
|
-
table_name_and_alias,
|
1540
|
-
aliased_table_name, first_key,
|
1541
|
-
aliased_join_table_name, second_key
|
1526
|
+
first_key = through_reflection.klass.base_class.to_s.classify.foreign_key
|
1527
|
+
second_key = options[:foreign_key] || primary_key
|
1528
|
+
end
|
1529
|
+
|
1530
|
+
unless through_reflection.klass.descends_from_active_record?
|
1531
|
+
jt_sti_extra = " AND %s.%s = %s" % [
|
1532
|
+
aliased_join_table_name,
|
1533
|
+
reflection.active_record.connection.quote_column_name(through_reflection.active_record.inheritance_column),
|
1534
|
+
through_reflection.klass.quote_value(through_reflection.klass.name.demodulize)]
|
1535
|
+
end
|
1536
|
+
when :belongs_to
|
1537
|
+
first_key = primary_key
|
1538
|
+
if reflection.options[:source_type]
|
1539
|
+
second_key = source_reflection.association_foreign_key
|
1540
|
+
jt_source_extra = " AND %s.%s = %s" % [
|
1541
|
+
aliased_join_table_name, reflection.active_record.connection.quote_column_name(reflection.source_reflection.options[:foreign_type]),
|
1542
|
+
klass.quote_value(reflection.options[:source_type])
|
1542
1543
|
]
|
1544
|
+
else
|
1545
|
+
second_key = source_reflection.options[:foreign_key] || klass.to_s.classify.foreign_key
|
1543
1546
|
end
|
1544
1547
|
end
|
1548
|
+
|
1549
|
+
" LEFT OUTER JOIN %s ON (%s.%s = %s.%s%s%s%s) " % [
|
1550
|
+
table_alias_for(through_reflection.klass.table_name, aliased_join_table_name),
|
1551
|
+
parent.aliased_table_name, reflection.active_record.connection.quote_column_name(parent.primary_key),
|
1552
|
+
aliased_join_table_name, reflection.active_record.connection.quote_column_name(jt_foreign_key),
|
1553
|
+
jt_as_extra, jt_source_extra, jt_sti_extra
|
1554
|
+
] +
|
1555
|
+
" LEFT OUTER JOIN %s ON (%s.%s = %s.%s%s) " % [
|
1556
|
+
table_name_and_alias,
|
1557
|
+
aliased_table_name, reflection.active_record.connection.quote_column_name(first_key),
|
1558
|
+
aliased_join_table_name, reflection.active_record.connection.quote_column_name(second_key),
|
1559
|
+
as_extra
|
1560
|
+
]
|
1545
1561
|
|
1546
1562
|
when reflection.macro == :has_many && reflection.options[:as]
|
1547
1563
|
" LEFT OUTER JOIN %s ON %s.%s = %s.%s AND %s.%s = %s" % [
|
@@ -1588,6 +1604,7 @@ module ActiveRecord
|
|
1588
1604
|
end
|
1589
1605
|
|
1590
1606
|
protected
|
1607
|
+
|
1591
1608
|
def pluralize(table_name)
|
1592
1609
|
ActiveRecord::Base.pluralize_table_names ? table_name.to_s.pluralize : table_name
|
1593
1610
|
end
|
@@ -138,7 +138,11 @@ module ActiveRecord
|
|
138
138
|
|
139
139
|
# Construct attributes for :through pointing to owner and associate.
|
140
140
|
def construct_join_attributes(associate)
|
141
|
-
construct_owner_attributes(@reflection.through_reflection).merge(@reflection.source_reflection.
|
141
|
+
returning construct_owner_attributes(@reflection.through_reflection).merge(@reflection.source_reflection.primary_key_name => associate.id) do |join_attributes|
|
142
|
+
if @reflection.options[:source_type]
|
143
|
+
join_attributes.merge!(@reflection.source_reflection.options[:foreign_type] => associate.class.base_class.name.to_s)
|
144
|
+
end
|
145
|
+
end
|
142
146
|
end
|
143
147
|
|
144
148
|
# Associate attributes pointing to owner, quoted.
|
@@ -176,6 +180,12 @@ module ActiveRecord
|
|
176
180
|
if @reflection.through_reflection.options[:as] || @reflection.source_reflection.macro == :belongs_to
|
177
181
|
reflection_primary_key = @reflection.klass.primary_key
|
178
182
|
source_primary_key = @reflection.source_reflection.primary_key_name
|
183
|
+
if @reflection.options[:source_type]
|
184
|
+
polymorphic_join = "AND %s.%s = %s" % [
|
185
|
+
@reflection.through_reflection.table_name, "#{@reflection.source_reflection.options[:foreign_type]}",
|
186
|
+
@owner.class.quote_value(@reflection.options[:source_type])
|
187
|
+
]
|
188
|
+
end
|
179
189
|
else
|
180
190
|
reflection_primary_key = @reflection.source_reflection.primary_key_name
|
181
191
|
source_primary_key = @reflection.klass.primary_key
|
data/lib/active_record/base.rb
CHANGED
@@ -479,7 +479,7 @@ module ActiveRecord #:nodoc:
|
|
479
479
|
# Deletes the record with the given +id+ without instantiating an object first. If an array of ids is provided, all of them
|
480
480
|
# are deleted.
|
481
481
|
def delete(id)
|
482
|
-
delete_all([ "#{primary_key} IN (?)", id ])
|
482
|
+
delete_all([ "#{connection.quote_column_name(primary_key)} IN (?)", id ])
|
483
483
|
end
|
484
484
|
|
485
485
|
# Destroys the record with the given +id+ by instantiating the object and calling #destroy (all the callbacks are the triggered).
|
@@ -526,12 +526,12 @@ module ActiveRecord #:nodoc:
|
|
526
526
|
# for looping over a collection where each element require a number of aggregate values. Like the DiscussionBoard
|
527
527
|
# that needs to list both the number of posts and comments.
|
528
528
|
def increment_counter(counter_name, id)
|
529
|
-
update_all "#{counter_name} = #{counter_name} + 1", "#{primary_key} = #{quote_value(id)}"
|
529
|
+
update_all "#{connection.quote_column_name(counter_name)} = #{connection.quote_column_name(counter_name)} + 1", "#{connection.quote_column_name(primary_key)} = #{quote_value(id)}"
|
530
530
|
end
|
531
531
|
|
532
532
|
# Works like increment_counter, but decrements instead.
|
533
533
|
def decrement_counter(counter_name, id)
|
534
|
-
update_all "#{counter_name} = #{counter_name} - 1", "#{primary_key} = #{quote_value(id)}"
|
534
|
+
update_all "#{connection.quote_column_name(counter_name)} = #{connection.quote_column_name(counter_name)} - 1", "#{connection.quote_column_name(primary_key)} = #{quote_value(id)}"
|
535
535
|
end
|
536
536
|
|
537
537
|
|
@@ -1020,7 +1020,7 @@ module ActiveRecord #:nodoc:
|
|
1020
1020
|
|
1021
1021
|
def find_one(id, options)
|
1022
1022
|
conditions = " AND (#{sanitize_sql(options[:conditions])})" if options[:conditions]
|
1023
|
-
options.update :conditions => "#{table_name}.#{primary_key} = #{quote_value(id,columns_hash[primary_key])}#{conditions}"
|
1023
|
+
options.update :conditions => "#{table_name}.#{connection.quote_column_name(primary_key)} = #{quote_value(id,columns_hash[primary_key])}#{conditions}"
|
1024
1024
|
|
1025
1025
|
# Use find_every(options).first since the primary key condition
|
1026
1026
|
# already ensures we have a single record. Using find_initial adds
|
@@ -1035,7 +1035,7 @@ module ActiveRecord #:nodoc:
|
|
1035
1035
|
def find_some(ids, options)
|
1036
1036
|
conditions = " AND (#{sanitize_sql(options[:conditions])})" if options[:conditions]
|
1037
1037
|
ids_list = ids.map { |id| quote_value(id,columns_hash[primary_key]) }.join(',')
|
1038
|
-
options.update :conditions => "#{table_name}.#{primary_key} IN (#{ids_list})#{conditions}"
|
1038
|
+
options.update :conditions => "#{table_name}.#{connection.quote_column_name(primary_key)} IN (#{ids_list})#{conditions}"
|
1039
1039
|
|
1040
1040
|
result = find_every(options)
|
1041
1041
|
|
@@ -1052,10 +1052,9 @@ module ActiveRecord #:nodoc:
|
|
1052
1052
|
def instantiate(record)
|
1053
1053
|
object =
|
1054
1054
|
if subclass_name = record[inheritance_column]
|
1055
|
-
# No type given.
|
1056
1055
|
if subclass_name.empty?
|
1056
|
+
# No type given.
|
1057
1057
|
allocate
|
1058
|
-
|
1059
1058
|
else
|
1060
1059
|
# Ignore type if no column is present since it was probably
|
1061
1060
|
# pulled in from a sloppy join.
|
@@ -1558,7 +1557,7 @@ module ActiveRecord #:nodoc:
|
|
1558
1557
|
unless new_record?
|
1559
1558
|
connection.delete <<-end_sql, "#{self.class.name} Destroy"
|
1560
1559
|
DELETE FROM #{self.class.table_name}
|
1561
|
-
WHERE #{self.class.primary_key} = #{quoted_id}
|
1560
|
+
WHERE #{connection.quote_column_name(self.class.primary_key)} = #{quoted_id}
|
1562
1561
|
end_sql
|
1563
1562
|
end
|
1564
1563
|
|
@@ -1797,7 +1796,7 @@ module ActiveRecord #:nodoc:
|
|
1797
1796
|
connection.update(
|
1798
1797
|
"UPDATE #{self.class.table_name} " +
|
1799
1798
|
"SET #{quoted_comma_pair_list(connection, attributes_with_quotes(false))} " +
|
1800
|
-
"WHERE #{self.class.primary_key} = #{quote_value(id)}",
|
1799
|
+
"WHERE #{connection.quote_column_name(self.class.primary_key)} = #{quote_value(id)}",
|
1801
1800
|
"#{self.class.name} Update"
|
1802
1801
|
)
|
1803
1802
|
end
|
@@ -301,18 +301,30 @@ class Fixtures < YAML::Omap
|
|
301
301
|
yaml_string << IO.read(subfixture_path)
|
302
302
|
end
|
303
303
|
yaml_string << IO.read(yaml_file_path)
|
304
|
+
|
304
305
|
begin
|
305
306
|
yaml = YAML::load(erb_render(yaml_string))
|
306
307
|
rescue Exception=>boom
|
307
308
|
raise Fixture::FormatError, "a YAML error occurred parsing #{yaml_file_path}. Please note that YAML must be consistently indented using spaces. Tabs are not allowed. Please have a look at http://www.yaml.org/faq.html\nThe exact error was:\n #{boom.class}: #{boom}"
|
308
|
-
end
|
309
|
+
end
|
310
|
+
|
309
311
|
if yaml
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
312
|
+
# If the file is an ordered map, extract its children.
|
313
|
+
yaml_value =
|
314
|
+
if yaml.respond_to?(:type_id) && yaml.respond_to?(:value)
|
315
|
+
yaml.value
|
316
|
+
else
|
317
|
+
[yaml]
|
318
|
+
end
|
319
|
+
|
320
|
+
yaml_value.each do |fixture|
|
321
|
+
fixture.each do |name, data|
|
322
|
+
unless data
|
323
|
+
raise Fixture::FormatError, "Bad data for #{@class_name} fixture named #{name} (nil)"
|
324
|
+
end
|
325
|
+
|
326
|
+
self[name] = Fixture.new(data, @class_name)
|
314
327
|
end
|
315
|
-
self[name] = Fixture.new(data, @class_name)
|
316
328
|
end
|
317
329
|
end
|
318
330
|
elsif File.file?(csv_file_path)
|
@@ -186,8 +186,12 @@ module ActiveRecord
|
|
186
186
|
if source_reflection.nil?
|
187
187
|
raise HasManyThroughSourceAssociationNotFoundError.new(self)
|
188
188
|
end
|
189
|
+
|
190
|
+
if options[:source_type] && source_reflection.options[:polymorphic].nil?
|
191
|
+
raise HasManyThroughAssociationPointlessSourceTypeError.new(active_record.name, self, source_reflection)
|
192
|
+
end
|
189
193
|
|
190
|
-
if source_reflection.options[:polymorphic]
|
194
|
+
if source_reflection.options[:polymorphic] && options[:source_type].nil?
|
191
195
|
raise HasManyThroughAssociationPolymorphicError.new(active_record.name, self, source_reflection)
|
192
196
|
end
|
193
197
|
|
@@ -205,7 +209,7 @@ module ActiveRecord
|
|
205
209
|
if options[:class_name]
|
206
210
|
options[:class_name]
|
207
211
|
elsif through_reflection # get the class_name of the belongs_to association of the through reflection
|
208
|
-
source_reflection.class_name
|
212
|
+
options[:source_type] || source_reflection.class_name
|
209
213
|
else
|
210
214
|
class_name = name.to_s.camelize
|
211
215
|
class_name = class_name.singularize if [ :has_many, :has_and_belongs_to_many ].include?(macro)
|
@@ -563,9 +563,9 @@ class Mysql
|
|
563
563
|
def scramble41(password, message)
|
564
564
|
return 0x00.chr if password.nil? or password.empty?
|
565
565
|
buf = [0x14]
|
566
|
-
s1 = Digest::SHA1.
|
567
|
-
s2 = Digest::SHA1.
|
568
|
-
x = Digest::SHA1.
|
566
|
+
s1 = Digest::SHA1.digest(password)
|
567
|
+
s2 = Digest::SHA1.digest(s1)
|
568
|
+
x = Digest::SHA1.digest(message + s2)
|
569
569
|
(0..s1.length - 1).each {|i| buf.push(s1[i] ^ x[i])}
|
570
570
|
buf.pack("C*")
|
571
571
|
end
|
@@ -1174,7 +1174,11 @@ class << Mysql
|
|
1174
1174
|
def finalizer(net)
|
1175
1175
|
proc {
|
1176
1176
|
net.clear
|
1177
|
-
|
1177
|
+
begin
|
1178
|
+
net.write(Mysql::COM_QUIT.chr)
|
1179
|
+
net.close
|
1180
|
+
rescue # Ignore IOError if socket is already closed.
|
1181
|
+
end
|
1178
1182
|
}
|
1179
1183
|
end
|
1180
1184
|
|
@@ -6,10 +6,12 @@ require 'fixtures/comment'
|
|
6
6
|
require 'fixtures/author'
|
7
7
|
require 'fixtures/category'
|
8
8
|
require 'fixtures/categorization'
|
9
|
+
require 'fixtures/vertex'
|
10
|
+
require 'fixtures/edge'
|
9
11
|
|
10
12
|
class AssociationsJoinModelTest < Test::Unit::TestCase
|
11
13
|
self.use_transactional_fixtures = false
|
12
|
-
fixtures :posts, :authors, :categories, :categorizations, :comments, :tags, :taggings, :author_favorites
|
14
|
+
fixtures :posts, :authors, :categories, :categorizations, :comments, :tags, :taggings, :author_favorites, :vertices
|
13
15
|
|
14
16
|
def test_has_many
|
15
17
|
assert authors(:david).categories.include?(categories(:general))
|
@@ -298,6 +300,18 @@ class AssociationsJoinModelTest < Test::Unit::TestCase
|
|
298
300
|
assert_equal [posts(:welcome), posts(:thinking)], tags(:general).taggings.find(:all, :include => :taggable)
|
299
301
|
end
|
300
302
|
end
|
303
|
+
|
304
|
+
def test_has_many_polymorphic_with_source_type
|
305
|
+
assert_equal [posts(:welcome), posts(:thinking)], tags(:general).tagged_posts
|
306
|
+
end
|
307
|
+
|
308
|
+
def test_eager_has_many_polymorphic_with_source_type
|
309
|
+
tag_with_include = Tag.find(tags(:general).id, :include => :tagged_posts)
|
310
|
+
desired = [posts(:welcome), posts(:thinking)]
|
311
|
+
assert_no_queries do
|
312
|
+
assert_equal desired, tag_with_include.tagged_posts
|
313
|
+
end
|
314
|
+
end
|
301
315
|
|
302
316
|
def test_has_many_through_has_many_find_all
|
303
317
|
assert_equal comments(:greetings), authors(:david).comments.find(:all, :order => 'comments.id').first
|
@@ -414,6 +428,9 @@ class AssociationsJoinModelTest < Test::Unit::TestCase
|
|
414
428
|
message = "Expected a Tagging in taggings collection, got #{wrong.class}.")
|
415
429
|
assert_equal(count + 4, post_thinking.tags.size)
|
416
430
|
assert_equal(count + 4, post_thinking.tags(true).size)
|
431
|
+
|
432
|
+
# Raises if the wrong reflection name is used to set the Edge belongs_to
|
433
|
+
assert_nothing_raised { vertices(:vertex_1).sinks << vertices(:vertex_5) }
|
417
434
|
end
|
418
435
|
|
419
436
|
def test_adding_junk_to_has_many_through_should_raise_type_mismatch
|
@@ -30,6 +30,7 @@ DROP TABLE keyboards;
|
|
30
30
|
DROP TABLE defaults;
|
31
31
|
DROP TABLE legacy_things;
|
32
32
|
DROP TABLE numeric_data;
|
33
|
+
DROP TABLE mixed_case_monkeys;
|
33
34
|
|
34
35
|
DROP DOMAIN D_BOOLEAN;
|
35
36
|
|
@@ -59,3 +60,4 @@ DROP GENERATOR keyboards_seq;
|
|
59
60
|
DROP GENERATOR defaults_seq;
|
60
61
|
DROP GENERATOR legacy_things_seq;
|
61
62
|
DROP GENERATOR numeric_data_seq;
|
63
|
+
DROP GENERATOR mixed_case_monkeys_seq;
|
@@ -295,3 +295,10 @@ CREATE TABLE numeric_data (
|
|
295
295
|
);
|
296
296
|
CREATE GENERATOR numeric_data_seq;
|
297
297
|
SET GENERATOR numeric_data_seq TO 10000;
|
298
|
+
|
299
|
+
CREATE TABLE mixed_case_monkeys (
|
300
|
+
"monkeyID" BIGINT NOT NULL,
|
301
|
+
"fleaCount" INTEGER
|
302
|
+
);
|
303
|
+
CREATE GENERATOR mixed_case_monkeys_seq;
|
304
|
+
SET GENERATOR mixed_case_monkeys_seq TO 10000;
|
@@ -260,3 +260,9 @@ CREATE TABLE "numeric_data" (
|
|
260
260
|
primary key ("id")
|
261
261
|
);
|
262
262
|
SET UNIQUE FOR numeric_data(id);
|
263
|
+
|
264
|
+
CREATE TABLE mixed_case_monkeys (
|
265
|
+
"monkeyID" integer DEFAULT unique,
|
266
|
+
"fleaCount" integer
|
267
|
+
);
|
268
|
+
SET UNIQUE FOR mixed_case_monkeys("monkeyID");
|
@@ -226,3 +226,9 @@ CREATE TABLE `numeric_data` (
|
|
226
226
|
`my_house_population` decimal(2),
|
227
227
|
`decimal_number_with_default` decimal(3,2) DEFAULT 2.78
|
228
228
|
) TYPE=InnoDB;
|
229
|
+
|
230
|
+
CREATE TABLE mixed_case_monkeys (
|
231
|
+
`monkeyID` int(11) NOT NULL auto_increment,
|
232
|
+
`fleaCount` int(11),
|
233
|
+
PRIMARY KEY (`monkeyID`)
|
234
|
+
) TYPE=InnoDB;
|
@@ -292,3 +292,11 @@ CREATE TABLE numeric_data (
|
|
292
292
|
go
|
293
293
|
CREATE PRIMARY KEY numeric_data (id)
|
294
294
|
go
|
295
|
+
|
296
|
+
CREATE TABLE mixed_case_monkeys (
|
297
|
+
monkeyID INTEGER NOT NULL DEFAULT _rowid,
|
298
|
+
fleaCount INTEGER
|
299
|
+
);
|
300
|
+
go
|
301
|
+
CREATE PRIMARY KEY mixed_case_monkeys (monkeyID)
|
302
|
+
go
|
@@ -30,6 +30,7 @@ drop table fk_test_has_fk;
|
|
30
30
|
drop table keyboards;
|
31
31
|
drop table legacy_things;
|
32
32
|
drop table numeric_data;
|
33
|
+
drop table mixed_case_monkeys;
|
33
34
|
|
34
35
|
drop sequence accounts_seq;
|
35
36
|
drop sequence funny_jokes_seq;
|
@@ -61,3 +62,4 @@ drop sequence fk_test_has_fk_seq;
|
|
61
62
|
drop sequence keyboards_seq;
|
62
63
|
drop sequence legacy_things_seq;
|
63
64
|
drop sequence numeric_data_seq;
|
65
|
+
drop sequence mixed_case_monkeys_seq;
|
@@ -317,3 +317,9 @@ CREATE TABLE numeric_data (
|
|
317
317
|
decimal_number_with_default decimal(3,2) DEFAULT 2.78
|
318
318
|
);
|
319
319
|
create sequence numeric_data_seq minvalue 10000;
|
320
|
+
|
321
|
+
CREATE TABLE mixed_case_monkeys (
|
322
|
+
"monkeyID" INTEGER NOT NULL PRIMARY KEY,
|
323
|
+
"fleaCount" INTEGER
|
324
|
+
);
|
325
|
+
create sequence mixed_case_monkeys_seq minvalue 10000;
|
data/test/fixtures/tag.rb
CHANGED
data/test/fixtures/vertex.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# This class models a vertex in a directed graph.
|
2
2
|
class Vertex < ActiveRecord::Base
|
3
3
|
has_many :sink_edges, :class_name => 'Edge', :foreign_key => 'source_id'
|
4
|
-
has_many :sinks, :through => :sink_edges
|
4
|
+
has_many :sinks, :through => :sink_edges
|
5
5
|
|
6
6
|
has_and_belongs_to_many :sources,
|
7
7
|
:class_name => 'Vertex', :join_table => 'edges',
|
data/test/pk_test.rb
CHANGED
@@ -4,9 +4,10 @@ require 'fixtures/reply'
|
|
4
4
|
require 'fixtures/subscriber'
|
5
5
|
require 'fixtures/movie'
|
6
6
|
require 'fixtures/keyboard'
|
7
|
+
require 'fixtures/mixed_case_monkey'
|
7
8
|
|
8
9
|
class PrimaryKeysTest < Test::Unit::TestCase
|
9
|
-
fixtures :topics, :subscribers, :movies
|
10
|
+
fixtures :topics, :subscribers, :movies, :mixed_case_monkeys
|
10
11
|
|
11
12
|
def test_integer_key
|
12
13
|
topic = Topic.find(1)
|
@@ -78,4 +79,26 @@ class PrimaryKeysTest < Test::Unit::TestCase
|
|
78
79
|
Topic.reset_primary_key
|
79
80
|
assert_equal "id", Topic.primary_key
|
80
81
|
end
|
82
|
+
|
83
|
+
def test_delete_should_quote_pkey
|
84
|
+
assert_nothing_raised { MixedCaseMonkey.delete(1) }
|
85
|
+
end
|
86
|
+
def test_increment_counter_should_quote_pkey_and_quote_counter_columns
|
87
|
+
assert_nothing_raised { MixedCaseMonkey.increment_counter(:fleaCount, 1) }
|
88
|
+
end
|
89
|
+
def test_decrement_counter_should_quote_pkey_and_quote_counter_columns
|
90
|
+
assert_nothing_raised { MixedCaseMonkey.decrement_counter(:fleaCount, 1) }
|
91
|
+
end
|
92
|
+
def test_find_with_one_id_should_quote_pkey
|
93
|
+
assert_nothing_raised { MixedCaseMonkey.find(1) }
|
94
|
+
end
|
95
|
+
def test_find_with_multiple_ids_should_quote_pkey
|
96
|
+
assert_nothing_raised { MixedCaseMonkey.find([1,2]) }
|
97
|
+
end
|
98
|
+
def test_instance_update_should_quote_pkey
|
99
|
+
assert_nothing_raised { MixedCaseMonkey.find(1).save }
|
100
|
+
end
|
101
|
+
def test_instance_destry_should_quote_pkey
|
102
|
+
assert_nothing_raised { MixedCaseMonkey.find(1).destroy }
|
103
|
+
end
|
81
104
|
end
|
metadata
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.9.
|
2
|
+
rubygems_version: 0.9.2
|
3
3
|
specification_version: 1
|
4
4
|
name: activerecord
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 1.15.
|
7
|
-
date: 2007-
|
6
|
+
version: 1.15.3
|
7
|
+
date: 2007-03-13 00:00:00 -05:00
|
8
8
|
summary: Implements the ActiveRecord pattern for ORM.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -228,6 +228,8 @@ files:
|
|
228
228
|
- test/fixtures/migrations_with_decimal
|
229
229
|
- test/fixtures/migrations_with_duplicate
|
230
230
|
- test/fixtures/migrations_with_missing_versions
|
231
|
+
- test/fixtures/mixed_case_monkey.rb
|
232
|
+
- test/fixtures/mixed_case_monkeys.yml
|
231
233
|
- test/fixtures/mixin.rb
|
232
234
|
- test/fixtures/mixins.yml
|
233
235
|
- test/fixtures/movie.rb
|
@@ -353,5 +355,5 @@ dependencies:
|
|
353
355
|
requirements:
|
354
356
|
- - "="
|
355
357
|
- !ruby/object:Gem::Version
|
356
|
-
version: 1.4.
|
358
|
+
version: 1.4.2
|
357
359
|
version:
|