activerecord 3.2.3 → 3.2.4.rc1
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.md +10 -1
- data/README.rdoc +1 -1
- data/lib/active_record/associations/collection_association.rb +14 -2
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +12 -5
- data/lib/active_record/associations/has_many_association.rb +6 -2
- data/lib/active_record/associations/has_many_through_association.rb +4 -0
- data/lib/active_record/associations/preloader/association.rb +3 -2
- data/lib/active_record/attribute_methods.rb +1 -0
- data/lib/active_record/attribute_methods/read.rb +6 -5
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +1 -0
- data/lib/active_record/base.rb +3 -4
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +20 -14
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +9 -1
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +1 -1
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +19 -8
- data/lib/active_record/connection_adapters/sqlite_adapter.rb +8 -1
- data/lib/active_record/fixtures.rb +26 -10
- data/lib/active_record/identity_map.rb +7 -1
- data/lib/active_record/inheritance.rb +16 -9
- data/lib/active_record/railtie.rb +7 -1
- data/lib/active_record/railties/databases.rake +2 -2
- data/lib/active_record/relation.rb +2 -0
- data/lib/active_record/relation/finder_methods.rb +1 -2
- data/lib/active_record/scoping/named.rb +3 -3
- data/lib/active_record/transactions.rb +3 -1
- data/lib/active_record/validations/uniqueness.rb +3 -3
- data/lib/active_record/version.rb +2 -2
- data/lib/rails/generators/active_record/migration/templates/migration.rb +2 -2
- metadata +40 -34
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,13 @@
|
|
1
|
-
## Rails 3.2.
|
1
|
+
## Rails 3.2.4 (unreleased) ##
|
2
|
+
|
3
|
+
* Perf fix: Don't load the records when doing assoc.delete_all.
|
4
|
+
GH #6289. *Jon Leighton*
|
5
|
+
|
6
|
+
* Association preloading shouldn't be affected by the current scoping.
|
7
|
+
This could cause infinite recursion and potentially other problems.
|
8
|
+
See GH #5667. *Jon Leighton*
|
9
|
+
|
10
|
+
## Rails 3.2.3 (March 30, 2012) ##
|
2
11
|
|
3
12
|
* Added find_or_create_by_{attribute}! dynamic method. *Andrew White*
|
4
13
|
|
data/README.rdoc
CHANGED
@@ -203,7 +203,7 @@ The latest version of Active Record can be installed with RubyGems:
|
|
203
203
|
|
204
204
|
Source code can be downloaded as part of the Rails project on GitHub
|
205
205
|
|
206
|
-
* https://github.com/rails/rails/tree/
|
206
|
+
* https://github.com/rails/rails/tree/3-2-stable/activerecord
|
207
207
|
|
208
208
|
|
209
209
|
== License
|
@@ -154,7 +154,7 @@ module ActiveRecord
|
|
154
154
|
#
|
155
155
|
# See delete for more info.
|
156
156
|
def delete_all
|
157
|
-
delete(
|
157
|
+
delete(:all).tap do
|
158
158
|
reset
|
159
159
|
loaded!
|
160
160
|
end
|
@@ -226,7 +226,17 @@ module ActiveRecord
|
|
226
226
|
# are actually removed from the database, that depends precisely on
|
227
227
|
# +delete_records+. They are in any case removed from the collection.
|
228
228
|
def delete(*records)
|
229
|
-
|
229
|
+
dependent = options[:dependent]
|
230
|
+
|
231
|
+
if records.first == :all
|
232
|
+
if loaded? || dependent == :destroy
|
233
|
+
delete_or_destroy(load_target, dependent)
|
234
|
+
else
|
235
|
+
delete_records(:all, dependent)
|
236
|
+
end
|
237
|
+
else
|
238
|
+
delete_or_destroy(records, dependent)
|
239
|
+
end
|
230
240
|
end
|
231
241
|
|
232
242
|
# Destroy +records+ and remove them from this association calling
|
@@ -481,6 +491,8 @@ module ActiveRecord
|
|
481
491
|
raise RecordNotSaved, "Failed to replace #{reflection.name} because one or more of the " \
|
482
492
|
"new records could not be saved."
|
483
493
|
end
|
494
|
+
|
495
|
+
target
|
484
496
|
end
|
485
497
|
|
486
498
|
def concat_records(records)
|
@@ -44,13 +44,20 @@ module ActiveRecord
|
|
44
44
|
|
45
45
|
def delete_records(records, method)
|
46
46
|
if sql = options[:delete_sql]
|
47
|
+
records = load_target if records == :all
|
47
48
|
records.each { |record| owner.connection.delete(interpolate(sql, record)) }
|
48
49
|
else
|
49
|
-
relation
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
50
|
+
relation = join_table
|
51
|
+
condition = relation[reflection.foreign_key].eq(owner.id)
|
52
|
+
|
53
|
+
unless records == :all
|
54
|
+
condition = condition.and(
|
55
|
+
relation[reflection.association_foreign_key].
|
56
|
+
in(records.map { |x| x.id }.compact)
|
57
|
+
)
|
58
|
+
end
|
59
|
+
|
60
|
+
owner.connection.delete(relation.where(condition).compile_delete)
|
54
61
|
end
|
55
62
|
end
|
56
63
|
|
@@ -89,8 +89,12 @@ module ActiveRecord
|
|
89
89
|
records.each { |r| r.destroy }
|
90
90
|
update_counter(-records.length) unless inverse_updates_counter_cache?
|
91
91
|
else
|
92
|
-
|
93
|
-
|
92
|
+
if records == :all
|
93
|
+
scope = scoped
|
94
|
+
else
|
95
|
+
keys = records.map { |r| r[reflection.association_primary_key] }
|
96
|
+
scope = scoped.where(reflection.association_primary_key => keys)
|
97
|
+
end
|
94
98
|
|
95
99
|
if method == :delete_all
|
96
100
|
update_counter(-scope.delete_all)
|
@@ -126,6 +126,10 @@ module ActiveRecord
|
|
126
126
|
def delete_records(records, method)
|
127
127
|
ensure_not_nested
|
128
128
|
|
129
|
+
# This is unoptimised; it will load all the target records
|
130
|
+
# even when we just want to delete everything.
|
131
|
+
records = load_target if records == :all
|
132
|
+
|
129
133
|
scope = through_association.scoped.where(construct_join_attributes(*records))
|
130
134
|
|
131
135
|
case method
|
@@ -77,7 +77,7 @@ module ActiveRecord
|
|
77
77
|
# Some databases impose a limit on the number of ids in a list (in Oracle it's 1000)
|
78
78
|
# Make several smaller queries if necessary or make one query if the adapter supports it
|
79
79
|
sliced = owner_keys.each_slice(model.connection.in_clause_length || owner_keys.size)
|
80
|
-
records = sliced.map { |slice| records_for(slice) }.flatten
|
80
|
+
records = sliced.map { |slice| records_for(slice).to_a }.flatten
|
81
81
|
end
|
82
82
|
|
83
83
|
# Each record may have multiple owners, and vice-versa
|
@@ -93,7 +93,8 @@ module ActiveRecord
|
|
93
93
|
end
|
94
94
|
|
95
95
|
def build_scope
|
96
|
-
scope = klass.
|
96
|
+
scope = klass.unscoped
|
97
|
+
scope.default_scoped = true
|
97
98
|
|
98
99
|
scope = scope.where(process_conditions(options[:conditions]))
|
99
100
|
scope = scope.where(process_conditions(preload_options[:conditions]))
|
@@ -64,6 +64,7 @@ module ActiveRecord
|
|
64
64
|
return if attribute_methods_generated?
|
65
65
|
superclass.define_attribute_methods unless self == base_class
|
66
66
|
super(column_names)
|
67
|
+
column_names.each { |name| define_external_attribute_method(name) }
|
67
68
|
@attribute_methods_generated = true
|
68
69
|
end
|
69
70
|
end
|
@@ -67,26 +67,27 @@ module ActiveRecord
|
|
67
67
|
# we first define with the __temp__ identifier, and then use alias method to
|
68
68
|
# rename it to what we want.
|
69
69
|
def define_method_attribute(attr_name)
|
70
|
-
cast_code = attribute_cast_code(attr_name)
|
71
|
-
|
72
70
|
generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1
|
73
71
|
def __temp__
|
74
|
-
#{internal_attribute_access_code(attr_name,
|
72
|
+
#{internal_attribute_access_code(attr_name, attribute_cast_code(attr_name))}
|
75
73
|
end
|
76
74
|
alias_method '#{attr_name}', :__temp__
|
77
75
|
undef_method :__temp__
|
78
76
|
STR
|
77
|
+
end
|
79
78
|
|
79
|
+
private
|
80
|
+
|
81
|
+
def define_external_attribute_method(attr_name)
|
80
82
|
generated_external_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1
|
81
83
|
def __temp__(v, attributes, attributes_cache, attr_name)
|
82
|
-
#{external_attribute_access_code(attr_name,
|
84
|
+
#{external_attribute_access_code(attr_name, attribute_cast_code(attr_name))}
|
83
85
|
end
|
84
86
|
alias_method '#{attr_name}', :__temp__
|
85
87
|
undef_method :__temp__
|
86
88
|
STR
|
87
89
|
end
|
88
90
|
|
89
|
-
private
|
90
91
|
def cacheable_column?(column)
|
91
92
|
attribute_types_cached_by_default.include?(column.type)
|
92
93
|
end
|
data/lib/active_record/base.rb
CHANGED
@@ -450,12 +450,12 @@ module ActiveRecord #:nodoc:
|
|
450
450
|
private
|
451
451
|
|
452
452
|
def relation #:nodoc:
|
453
|
-
|
453
|
+
relation ||= Relation.new(self, arel_table)
|
454
454
|
|
455
455
|
if finder_needs_type_condition?
|
456
|
-
|
456
|
+
relation.where(type_condition).create_with(inheritance_column.to_sym => sti_name)
|
457
457
|
else
|
458
|
-
|
458
|
+
relation
|
459
459
|
end
|
460
460
|
end
|
461
461
|
end
|
@@ -489,7 +489,6 @@ module ActiveRecord #:nodoc:
|
|
489
489
|
@marked_for_destruction = false
|
490
490
|
@previously_changed = {}
|
491
491
|
@changed_attributes = {}
|
492
|
-
@relation = nil
|
493
492
|
|
494
493
|
ensure_proper_type
|
495
494
|
|
@@ -92,14 +92,18 @@ module ActiveRecord
|
|
92
92
|
# #connection can be called any number of times; the connection is
|
93
93
|
# held in a hash keyed by the thread id.
|
94
94
|
def connection
|
95
|
-
|
95
|
+
synchronize do
|
96
|
+
@reserved_connections[current_connection_id] ||= checkout
|
97
|
+
end
|
96
98
|
end
|
97
99
|
|
98
100
|
# Is there an open connection that is being used for the current thread?
|
99
101
|
def active_connection?
|
100
|
-
|
101
|
-
|
102
|
-
|
102
|
+
synchronize do
|
103
|
+
@reserved_connections.fetch(current_connection_id) {
|
104
|
+
return false
|
105
|
+
}.in_use?
|
106
|
+
end
|
103
107
|
end
|
104
108
|
|
105
109
|
# Signal that the thread is finished with the current connection.
|
@@ -286,17 +290,19 @@ connection. For example: ActiveRecord::Base.connection.close
|
|
286
290
|
private
|
287
291
|
|
288
292
|
def release(conn)
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
@reserved_connections
|
296
|
-
|
297
|
-
|
293
|
+
synchronize do
|
294
|
+
thread_id = nil
|
295
|
+
|
296
|
+
if @reserved_connections[current_connection_id] == conn
|
297
|
+
thread_id = current_connection_id
|
298
|
+
else
|
299
|
+
thread_id = @reserved_connections.keys.find { |k|
|
300
|
+
@reserved_connections[k] == conn
|
301
|
+
}
|
302
|
+
end
|
298
303
|
|
299
|
-
|
304
|
+
@reserved_connections.delete thread_id if thread_id
|
305
|
+
end
|
300
306
|
end
|
301
307
|
|
302
308
|
def new_connection
|
@@ -269,7 +269,15 @@ module ActiveRecord
|
|
269
269
|
# remove_column(:suppliers, :qualification)
|
270
270
|
# remove_columns(:suppliers, :qualification, :experience)
|
271
271
|
def remove_column(table_name, *column_names)
|
272
|
-
|
272
|
+
if column_names.flatten!
|
273
|
+
message = 'Passing array to remove_columns is deprecated, please use ' +
|
274
|
+
'multiple arguments, like: `remove_columns(:posts, :foo, :bar)`'
|
275
|
+
ActiveSupport::Deprecation.warn message, caller
|
276
|
+
end
|
277
|
+
|
278
|
+
columns_for_remove(table_name, *column_names).each do |column_name|
|
279
|
+
execute "ALTER TABLE #{quote_table_name(table_name)} DROP #{column_name}"
|
280
|
+
end
|
273
281
|
end
|
274
282
|
alias :remove_columns :remove_column
|
275
283
|
|
@@ -525,7 +525,7 @@ module ActiveRecord
|
|
525
525
|
def pk_and_sequence_for(table)
|
526
526
|
execute_and_free("SHOW CREATE TABLE #{quote_table_name(table)}", 'SCHEMA') do |result|
|
527
527
|
create_table = each_hash(result).first[:"Create Table"]
|
528
|
-
if create_table.to_s =~ /PRIMARY KEY\s+\((.+)\)/
|
528
|
+
if create_table.to_s =~ /PRIMARY KEY\s+(?:USING\s+\w+\s+)?\((.+)\)/
|
529
529
|
keys = $1.split(",").map { |key| key.gsub(/[`"]/, "") }
|
530
530
|
keys.length == 1 ? [keys.first, nil] : nil
|
531
531
|
else
|
@@ -264,7 +264,7 @@ module ActiveRecord
|
|
264
264
|
|
265
265
|
# increase timeout so mysql server doesn't disconnect us
|
266
266
|
wait_timeout = @config[:wait_timeout]
|
267
|
-
wait_timeout =
|
267
|
+
wait_timeout = 2147483 unless wait_timeout.is_a?(Fixnum)
|
268
268
|
variable_assignments << "@@wait_timeout = #{wait_timeout}"
|
269
269
|
|
270
270
|
execute("SET #{variable_assignments.join(', ')}", :skip_logging)
|
@@ -1067,14 +1067,25 @@ module ActiveRecord
|
|
1067
1067
|
|
1068
1068
|
# Maps logical Rails types to PostgreSQL-specific data types.
|
1069
1069
|
def type_to_sql(type, limit = nil, precision = nil, scale = nil)
|
1070
|
-
|
1071
|
-
|
1072
|
-
|
1073
|
-
|
1074
|
-
|
1075
|
-
when
|
1076
|
-
|
1077
|
-
|
1070
|
+
case type.to_s
|
1071
|
+
when 'binary'
|
1072
|
+
# PostgreSQL doesn't support limits on binary (bytea) columns.
|
1073
|
+
# The hard limit is 1Gb, because of a 32-bit size field, and TOAST.
|
1074
|
+
case limit
|
1075
|
+
when nil, 0..0x3fffffff; super(type)
|
1076
|
+
else raise(ActiveRecordError, "No binary type has byte size #{limit}.")
|
1077
|
+
end
|
1078
|
+
when 'integer'
|
1079
|
+
return 'integer' unless limit
|
1080
|
+
|
1081
|
+
case limit
|
1082
|
+
when 1, 2; 'smallint'
|
1083
|
+
when 3, 4; 'integer'
|
1084
|
+
when 5..8; 'bigint'
|
1085
|
+
else raise(ActiveRecordError, "No integer type has byte size #{limit}. Use a numeric with precision 0 instead.")
|
1086
|
+
end
|
1087
|
+
else
|
1088
|
+
super
|
1078
1089
|
end
|
1079
1090
|
end
|
1080
1091
|
|
@@ -407,7 +407,14 @@ module ActiveRecord
|
|
407
407
|
|
408
408
|
def remove_column(table_name, *column_names) #:nodoc:
|
409
409
|
raise ArgumentError.new("You must specify at least one column name. Example: remove_column(:people, :first_name)") if column_names.empty?
|
410
|
-
|
410
|
+
|
411
|
+
if column_names.flatten!
|
412
|
+
message = 'Passing array to remove_columns is deprecated, please use ' +
|
413
|
+
'multiple arguments, like: `remove_columns(:posts, :foo, :bar)`'
|
414
|
+
ActiveSupport::Deprecation.warn message, caller
|
415
|
+
end
|
416
|
+
|
417
|
+
column_names.each do |column_name|
|
411
418
|
alter_table(table_name) do |definition|
|
412
419
|
definition.columns.delete(definition[column_name])
|
413
420
|
end
|
@@ -419,11 +419,15 @@ module ActiveRecord
|
|
419
419
|
cache_for_connection(connection).update(fixtures_map)
|
420
420
|
end
|
421
421
|
|
422
|
-
|
422
|
+
#--
|
423
|
+
# TODO:NOTE: in the next version, the __with_new_arity suffix and
|
424
|
+
# the method with the old arity will be removed.
|
425
|
+
#++
|
426
|
+
def self.instantiate_fixtures__with_new_arity(object, fixture_set, load_instances = true) # :nodoc:
|
423
427
|
if load_instances
|
424
|
-
|
428
|
+
fixture_set.each do |fixture_name, fixture|
|
425
429
|
begin
|
426
|
-
object.instance_variable_set "@#{
|
430
|
+
object.instance_variable_set "@#{fixture_name}", fixture.find
|
427
431
|
rescue FixtureClassNotFound
|
428
432
|
nil
|
429
433
|
end
|
@@ -431,9 +435,24 @@ module ActiveRecord
|
|
431
435
|
end
|
432
436
|
end
|
433
437
|
|
438
|
+
# The use with parameters <tt>(object, fixture_set_name, fixture_set, load_instances = true)</tt> is deprecated, +fixture_set_name+ parameter is not used.
|
439
|
+
# Use as:
|
440
|
+
#
|
441
|
+
# instantiate_fixtures(object, fixture_set, load_instances = true)
|
442
|
+
def self.instantiate_fixtures(object, fixture_set, load_instances = true, rails_3_2_compatibility_argument = true)
|
443
|
+
unless load_instances == true || load_instances == false
|
444
|
+
ActiveSupport::Deprecation.warn(
|
445
|
+
"ActiveRecord::Fixtures.instantiate_fixtures with parameters (object, fixture_set_name, fixture_set, load_instances = true) is deprecated and shall be removed from future releases. Use it with parameters (object, fixture_set, load_instances = true) instead (skip fixture_set_name).",
|
446
|
+
caller)
|
447
|
+
fixture_set = load_instances
|
448
|
+
load_instances = rails_3_2_compatibility_argument
|
449
|
+
end
|
450
|
+
instantiate_fixtures__with_new_arity(object, fixture_set, load_instances)
|
451
|
+
end
|
452
|
+
|
434
453
|
def self.instantiate_all_loaded_fixtures(object, load_instances = true)
|
435
|
-
all_loaded_fixtures.
|
436
|
-
ActiveRecord::Fixtures.instantiate_fixtures(object,
|
454
|
+
all_loaded_fixtures.each_value do |fixture_set|
|
455
|
+
ActiveRecord::Fixtures.instantiate_fixtures(object, fixture_set, load_instances)
|
437
456
|
end
|
438
457
|
end
|
439
458
|
|
@@ -659,9 +678,6 @@ module ActiveRecord
|
|
659
678
|
"#{@fixture_path}.yml"
|
660
679
|
end
|
661
680
|
|
662
|
-
def yaml_fixtures_key(path)
|
663
|
-
::File.basename(@fixture_path).split(".").first
|
664
|
-
end
|
665
681
|
end
|
666
682
|
|
667
683
|
class Fixture #:nodoc:
|
@@ -893,8 +909,8 @@ module ActiveRecord
|
|
893
909
|
ActiveRecord::Fixtures.instantiate_all_loaded_fixtures(self, load_instances?)
|
894
910
|
else
|
895
911
|
raise RuntimeError, 'Load fixtures before instantiating them.' if @loaded_fixtures.nil?
|
896
|
-
@loaded_fixtures.
|
897
|
-
ActiveRecord::Fixtures.instantiate_fixtures(self,
|
912
|
+
@loaded_fixtures.each_value do |fixture_set|
|
913
|
+
ActiveRecord::Fixtures.instantiate_fixtures(self, fixture_set, load_instances?)
|
898
914
|
end
|
899
915
|
end
|
900
916
|
end
|
@@ -90,7 +90,7 @@ module ActiveRecord
|
|
90
90
|
end
|
91
91
|
|
92
92
|
def add(record)
|
93
|
-
repository[record.class.symbolized_sti_name][record.id] = record
|
93
|
+
repository[record.class.symbolized_sti_name][record.id] = record if contain_all_columns?(record)
|
94
94
|
end
|
95
95
|
|
96
96
|
def remove(record)
|
@@ -104,6 +104,12 @@ module ActiveRecord
|
|
104
104
|
def clear
|
105
105
|
repository.clear
|
106
106
|
end
|
107
|
+
|
108
|
+
private
|
109
|
+
|
110
|
+
def contain_all_columns?(record)
|
111
|
+
(record.class.column_names - record.attribute_names).empty?
|
112
|
+
end
|
107
113
|
end
|
108
114
|
|
109
115
|
# Reinitialize an Identity Map model object from +coder+.
|
@@ -63,15 +63,7 @@ module ActiveRecord
|
|
63
63
|
record_id = sti_class.primary_key && record[sti_class.primary_key]
|
64
64
|
|
65
65
|
if ActiveRecord::IdentityMap.enabled? && record_id
|
66
|
-
|
67
|
-
record_id = record_id.to_i
|
68
|
-
end
|
69
|
-
if instance = IdentityMap.get(sti_class, record_id)
|
70
|
-
instance.reinit_with('attributes' => record)
|
71
|
-
else
|
72
|
-
instance = sti_class.allocate.init_with('attributes' => record)
|
73
|
-
IdentityMap.add(instance)
|
74
|
-
end
|
66
|
+
instance = use_identity_map(sti_class, record_id, record)
|
75
67
|
else
|
76
68
|
instance = sti_class.allocate.init_with('attributes' => record)
|
77
69
|
end
|
@@ -122,6 +114,21 @@ module ActiveRecord
|
|
122
114
|
|
123
115
|
private
|
124
116
|
|
117
|
+
def use_identity_map(sti_class, record_id, record)
|
118
|
+
if (column = sti_class.columns_hash[sti_class.primary_key]) && column.number?
|
119
|
+
record_id = record_id.to_i
|
120
|
+
end
|
121
|
+
|
122
|
+
if instance = IdentityMap.get(sti_class, record_id)
|
123
|
+
instance.reinit_with('attributes' => record)
|
124
|
+
else
|
125
|
+
instance = sti_class.allocate.init_with('attributes' => record)
|
126
|
+
IdentityMap.add(instance)
|
127
|
+
end
|
128
|
+
|
129
|
+
instance
|
130
|
+
end
|
131
|
+
|
125
132
|
def find_sti_class(type_name)
|
126
133
|
if type_name.blank? || !columns_hash.include?(inheritance_column)
|
127
134
|
self
|
@@ -72,7 +72,13 @@ module ActiveRecord
|
|
72
72
|
# and then establishes the connection.
|
73
73
|
initializer "active_record.initialize_database" do |app|
|
74
74
|
ActiveSupport.on_load(:active_record) do
|
75
|
-
|
75
|
+
db_connection_type = "DATABASE_URL"
|
76
|
+
unless ENV['DATABASE_URL']
|
77
|
+
db_connection_type = "database.yml"
|
78
|
+
self.configurations = app.config.database_configuration
|
79
|
+
end
|
80
|
+
Rails.logger.info "Connecting to database specified by #{db_connection_type}"
|
81
|
+
|
76
82
|
establish_connection
|
77
83
|
end
|
78
84
|
end
|
@@ -387,9 +387,9 @@ db_namespace = namespace :db do
|
|
387
387
|
set_psql_env(abcs[Rails.env])
|
388
388
|
search_path = abcs[Rails.env]['schema_search_path']
|
389
389
|
unless search_path.blank?
|
390
|
-
search_path = search_path.split(",").map{|search_path_part| "--schema=#{search_path_part.strip}" }.join(" ")
|
390
|
+
search_path = search_path.split(",").map{|search_path_part| "--schema=#{Shellwords.escape(search_path_part.strip)}" }.join(" ")
|
391
391
|
end
|
392
|
-
`pg_dump -i -s -x -O -f #{filename} #{search_path} #{abcs[Rails.env]['database']}`
|
392
|
+
`pg_dump -i -s -x -O -f #{Shellwords.escape(filename)} #{search_path} #{Shellwords.escape(abcs[Rails.env]['database'])}`
|
393
393
|
raise 'Error dumping database' if $?.exitstatus == 1
|
394
394
|
when /sqlite/
|
395
395
|
dbfile = abcs[Rails.env]['database']
|
@@ -403,6 +403,8 @@ module ActiveRecord
|
|
403
403
|
# If you need to destroy dependent associations or call your <tt>before_*</tt> or
|
404
404
|
# +after_destroy+ callbacks, use the +destroy_all+ method instead.
|
405
405
|
def delete_all(conditions = nil)
|
406
|
+
raise ActiveRecordError.new("delete_all doesn't support limit scope") if self.limit_value
|
407
|
+
|
406
408
|
IdentityMap.repository[symbolized_base_class] = {} if IdentityMap.enabled?
|
407
409
|
if conditions
|
408
410
|
where(conditions).delete_all
|
@@ -185,9 +185,8 @@ module ActiveRecord
|
|
185
185
|
# Person.exists?(['name LIKE ?', "%#{query}%"])
|
186
186
|
# Person.exists?
|
187
187
|
def exists?(id = false)
|
188
|
-
return false if id.nil?
|
189
|
-
|
190
188
|
id = id.id if ActiveRecord::Base === id
|
189
|
+
return false if id.nil?
|
191
190
|
|
192
191
|
join_dependency = construct_join_dependency_for_association_find
|
193
192
|
relation = construct_relation_for_association_find(join_dependency)
|
@@ -34,7 +34,7 @@ module ActiveRecord
|
|
34
34
|
if current_scope
|
35
35
|
current_scope.clone
|
36
36
|
else
|
37
|
-
scope = relation
|
37
|
+
scope = relation
|
38
38
|
scope.default_scoped = true
|
39
39
|
scope
|
40
40
|
end
|
@@ -48,7 +48,7 @@ module ActiveRecord
|
|
48
48
|
if current_scope
|
49
49
|
current_scope.scope_for_create
|
50
50
|
else
|
51
|
-
scope = relation
|
51
|
+
scope = relation
|
52
52
|
scope.default_scoped = true
|
53
53
|
scope.scope_for_create
|
54
54
|
end
|
@@ -191,7 +191,7 @@ module ActiveRecord
|
|
191
191
|
protected
|
192
192
|
|
193
193
|
def valid_scope_name?(name)
|
194
|
-
if respond_to?(name, true)
|
194
|
+
if logger && respond_to?(name, true)
|
195
195
|
logger.warn "Creating scope :#{name}. " \
|
196
196
|
"Overwriting existing method #{self.name}.#{name}."
|
197
197
|
end
|
@@ -327,7 +327,8 @@ module ActiveRecord
|
|
327
327
|
@_start_transaction_state[:level] = (@_start_transaction_state[:level] || 0) - 1
|
328
328
|
if @_start_transaction_state[:level] < 1
|
329
329
|
restore_state = remove_instance_variable(:@_start_transaction_state)
|
330
|
-
|
330
|
+
was_frozen = @attributes.frozen?
|
331
|
+
@attributes = @attributes.dup if was_frozen
|
331
332
|
@new_record = restore_state[:new_record]
|
332
333
|
@destroyed = restore_state[:destroyed]
|
333
334
|
if restore_state.has_key?(:id)
|
@@ -336,6 +337,7 @@ module ActiveRecord
|
|
336
337
|
@attributes.delete(self.class.primary_key)
|
337
338
|
@attributes_cache.delete(self.class.primary_key)
|
338
339
|
end
|
340
|
+
@attributes.freeze if was_frozen
|
339
341
|
end
|
340
342
|
end
|
341
343
|
end
|
@@ -54,13 +54,13 @@ module ActiveRecord
|
|
54
54
|
|
55
55
|
def build_relation(klass, table, attribute, value) #:nodoc:
|
56
56
|
column = klass.columns_hash[attribute.to_s]
|
57
|
-
value = column.limit ? value.to_s.mb_chars[0, column.limit] : value.to_s if column.text?
|
57
|
+
value = column.limit ? value.to_s.mb_chars[0, column.limit] : value.to_s if value && column.text?
|
58
58
|
|
59
59
|
if !options[:case_sensitive] && value && column.text?
|
60
60
|
# will use SQL LOWER function before comparison, unless it detects a case insensitive collation
|
61
61
|
relation = klass.connection.case_insensitive_comparison(table, attribute, column, value)
|
62
62
|
else
|
63
|
-
value = klass.connection.case_sensitive_modifier(value)
|
63
|
+
value = klass.connection.case_sensitive_modifier(value) if value
|
64
64
|
relation = table[attribute].eq(value)
|
65
65
|
end
|
66
66
|
|
@@ -81,7 +81,7 @@ module ActiveRecord
|
|
81
81
|
#
|
82
82
|
# class Person < ActiveRecord::Base
|
83
83
|
# validates_uniqueness_of :user_name, :scope => :account_id
|
84
|
-
# end
|
84
|
+
# end
|
85
85
|
#
|
86
86
|
# Or even multiple scope parameters. For example, making sure that a teacher can only be on the schedule once
|
87
87
|
# per semester for a particular class.
|
@@ -13,9 +13,9 @@ class <%= migration_class_name %> < ActiveRecord::Migration
|
|
13
13
|
<% attributes.each do |attribute| -%>
|
14
14
|
<%- if migration_action -%>
|
15
15
|
<%= migration_action %>_column :<%= table_name %>, :<%= attribute.name %><% if migration_action == 'add' %>, :<%= attribute.type %><%= attribute.inject_options %><% end %>
|
16
|
-
|
16
|
+
<%- if attribute.has_index? && migration_action == 'add' -%>
|
17
17
|
add_index :<%= table_name %>, :<%= attribute.index_name %><%= attribute.inject_index_options %>
|
18
|
-
|
18
|
+
<%- end -%>
|
19
19
|
<%- end -%>
|
20
20
|
<%- end -%>
|
21
21
|
end
|
metadata
CHANGED
@@ -1,13 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: -3869655734
|
5
|
+
prerelease: 6
|
6
6
|
segments:
|
7
7
|
- 3
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
|
9
|
+
- 4
|
10
|
+
- rc
|
11
|
+
- 1
|
12
|
+
version: 3.2.4.rc1
|
11
13
|
platform: ruby
|
12
14
|
authors:
|
13
15
|
- David Heinemeier Hansson
|
@@ -15,43 +17,48 @@ autorequire:
|
|
15
17
|
bindir: bin
|
16
18
|
cert_chain: []
|
17
19
|
|
18
|
-
date: 2012-
|
19
|
-
default_executable:
|
20
|
+
date: 2012-05-28 00:00:00 Z
|
20
21
|
dependencies:
|
21
22
|
- !ruby/object:Gem::Dependency
|
22
|
-
|
23
|
+
name: activesupport
|
24
|
+
prerelease: false
|
25
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
23
26
|
none: false
|
24
27
|
requirements:
|
25
28
|
- - "="
|
26
29
|
- !ruby/object:Gem::Version
|
27
|
-
hash:
|
30
|
+
hash: -3869655734
|
28
31
|
segments:
|
29
32
|
- 3
|
30
33
|
- 2
|
31
|
-
-
|
32
|
-
|
33
|
-
|
34
|
+
- 4
|
35
|
+
- rc
|
36
|
+
- 1
|
37
|
+
version: 3.2.4.rc1
|
34
38
|
type: :runtime
|
35
|
-
|
36
|
-
prerelease: false
|
39
|
+
version_requirements: *id001
|
37
40
|
- !ruby/object:Gem::Dependency
|
38
|
-
|
41
|
+
name: activemodel
|
42
|
+
prerelease: false
|
43
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
44
|
none: false
|
40
45
|
requirements:
|
41
46
|
- - "="
|
42
47
|
- !ruby/object:Gem::Version
|
43
|
-
hash:
|
48
|
+
hash: -3869655734
|
44
49
|
segments:
|
45
50
|
- 3
|
46
51
|
- 2
|
47
|
-
-
|
48
|
-
|
49
|
-
|
52
|
+
- 4
|
53
|
+
- rc
|
54
|
+
- 1
|
55
|
+
version: 3.2.4.rc1
|
50
56
|
type: :runtime
|
51
|
-
|
52
|
-
prerelease: false
|
57
|
+
version_requirements: *id002
|
53
58
|
- !ruby/object:Gem::Dependency
|
54
|
-
|
59
|
+
name: arel
|
60
|
+
prerelease: false
|
61
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
55
62
|
none: false
|
56
63
|
requirements:
|
57
64
|
- - ~>
|
@@ -62,12 +69,12 @@ dependencies:
|
|
62
69
|
- 0
|
63
70
|
- 2
|
64
71
|
version: 3.0.2
|
65
|
-
requirement: *id003
|
66
72
|
type: :runtime
|
67
|
-
|
68
|
-
prerelease: false
|
73
|
+
version_requirements: *id003
|
69
74
|
- !ruby/object:Gem::Dependency
|
70
|
-
|
75
|
+
name: tzinfo
|
76
|
+
prerelease: false
|
77
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
71
78
|
none: false
|
72
79
|
requirements:
|
73
80
|
- - ~>
|
@@ -78,10 +85,8 @@ dependencies:
|
|
78
85
|
- 3
|
79
86
|
- 29
|
80
87
|
version: 0.3.29
|
81
|
-
requirement: *id004
|
82
88
|
type: :runtime
|
83
|
-
|
84
|
-
prerelease: false
|
89
|
+
version_requirements: *id004
|
85
90
|
description: Databases on Rails. Build a persistent domain model by mapping database tables to Ruby classes. Strong conventions for associations, validations, aggregations, migrations, and testing come baked-in.
|
86
91
|
email: david@loudthinking.com
|
87
92
|
executables: []
|
@@ -240,7 +245,6 @@ files:
|
|
240
245
|
- lib/rails/generators/active_record/session_migration/session_migration_generator.rb
|
241
246
|
- lib/rails/generators/active_record/session_migration/templates/migration.rb
|
242
247
|
- lib/rails/generators/active_record.rb
|
243
|
-
has_rdoc: true
|
244
248
|
homepage: http://www.rubyonrails.org
|
245
249
|
licenses: []
|
246
250
|
|
@@ -264,16 +268,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
264
268
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
265
269
|
none: false
|
266
270
|
requirements:
|
267
|
-
- - "
|
271
|
+
- - ">"
|
268
272
|
- !ruby/object:Gem::Version
|
269
|
-
hash:
|
273
|
+
hash: 25
|
270
274
|
segments:
|
271
|
-
-
|
272
|
-
|
275
|
+
- 1
|
276
|
+
- 3
|
277
|
+
- 1
|
278
|
+
version: 1.3.1
|
273
279
|
requirements: []
|
274
280
|
|
275
281
|
rubyforge_project:
|
276
|
-
rubygems_version: 1.
|
282
|
+
rubygems_version: 1.8.22
|
277
283
|
signing_key:
|
278
284
|
specification_version: 3
|
279
285
|
summary: Object-relational mapper framework (part of Rails).
|