activerecord 3.2.0.rc2 → 3.2.0
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 +32 -2
- data/lib/active_record/attribute_methods.rb +17 -8
- data/lib/active_record/connection_adapters/column.rb +2 -2
- data/lib/active_record/counter_cache.rb +2 -1
- data/lib/active_record/locking/pessimistic.rb +22 -0
- data/lib/active_record/migration.rb +10 -2
- data/lib/active_record/model_schema.rb +7 -3
- data/lib/active_record/railties/jdbcmysql_error.rb +1 -1
- data/lib/active_record/relation/query_methods.rb +12 -2
- data/lib/active_record/version.rb +1 -1
- metadata +53 -98
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,34 @@
|
|
1
|
-
## Rails 3.2.0 (
|
1
|
+
## Rails 3.2.0 (January 20, 2012) ##
|
2
|
+
|
3
|
+
* Added a `with_lock` method to ActiveRecord objects, which starts
|
4
|
+
a transaction, locks the object (pessimistically) and yields to the block.
|
5
|
+
The method takes one (optional) parameter and passes it to `lock!`.
|
6
|
+
|
7
|
+
Before:
|
8
|
+
|
9
|
+
class Order < ActiveRecord::Base
|
10
|
+
def cancel!
|
11
|
+
transaction do
|
12
|
+
lock!
|
13
|
+
# ... cancelling logic
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
After:
|
19
|
+
|
20
|
+
class Order < ActiveRecord::Base
|
21
|
+
def cancel!
|
22
|
+
with_lock do
|
23
|
+
# ... cancelling logic
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
*Olek Janiszewski*
|
29
|
+
|
30
|
+
* 'on' and 'ON' boolean columns values are type casted to true
|
31
|
+
*Santiago Pastorino*
|
2
32
|
|
3
33
|
* Added ability to run migrations only for given scope, which allows
|
4
34
|
to run migrations only from one engine (for example to revert changes
|
@@ -7,7 +37,7 @@
|
|
7
37
|
Example:
|
8
38
|
rake db:migrate SCOPE=blog
|
9
39
|
|
10
|
-
|
40
|
+
*Piotr Sarnacki*
|
11
41
|
|
12
42
|
* Migrations copied from engines are now scoped with engine's name,
|
13
43
|
for example 01_create_posts.blog.rb. *Piotr Sarnacki*
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'active_support/core_ext/enumerable'
|
2
2
|
require 'active_support/deprecation'
|
3
|
+
require 'thread'
|
3
4
|
|
4
5
|
module ActiveRecord
|
5
6
|
# = Active Record Attribute Methods
|
@@ -21,23 +22,31 @@ module ActiveRecord
|
|
21
22
|
# Returns the value of the attribute identified by <tt>attr_name</tt> after it has been typecast (for example,
|
22
23
|
# "2004-12-12" in a data column is cast to a date object, like Date.new(2004, 12, 12)).
|
23
24
|
# (Alias for the protected read_attribute method).
|
24
|
-
|
25
|
+
def [](attr_name)
|
26
|
+
read_attribute(attr_name)
|
27
|
+
end
|
25
28
|
|
26
29
|
# Updates the attribute identified by <tt>attr_name</tt> with the specified +value+.
|
27
30
|
# (Alias for the protected write_attribute method).
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
+
def []=(attr_name, value)
|
32
|
+
write_attribute(attr_name, value)
|
33
|
+
end
|
31
34
|
end
|
32
35
|
|
33
36
|
module ClassMethods
|
34
37
|
# Generates all the attribute related methods for columns in the database
|
35
38
|
# accessors, mutators and query methods.
|
36
39
|
def define_attribute_methods
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
40
|
+
# Use a mutex; we don't want two thread simaltaneously trying to define
|
41
|
+
# attribute methods.
|
42
|
+
@attribute_methods_mutex ||= Mutex.new
|
43
|
+
|
44
|
+
@attribute_methods_mutex.synchronize do
|
45
|
+
return if attribute_methods_generated?
|
46
|
+
superclass.define_attribute_methods unless self == base_class
|
47
|
+
super(column_names)
|
48
|
+
@attribute_methods_generated = true
|
49
|
+
end
|
41
50
|
end
|
42
51
|
|
43
52
|
def attribute_methods_generated?
|
@@ -5,8 +5,8 @@ module ActiveRecord
|
|
5
5
|
module ConnectionAdapters
|
6
6
|
# An abstract definition of a column in a table.
|
7
7
|
class Column
|
8
|
-
TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE'].to_set
|
9
|
-
FALSE_VALUES = [false, 0, '0', 'f', 'F', 'false', 'FALSE'].to_set
|
8
|
+
TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE', 'on', 'ON'].to_set
|
9
|
+
FALSE_VALUES = [false, 0, '0', 'f', 'F', 'false', 'FALSE', 'off', 'OFF'].to_set
|
10
10
|
|
11
11
|
module Format
|
12
12
|
ISO_DATE = /\A(\d{4})-(\d\d)-(\d\d)\z/
|
@@ -25,9 +25,10 @@ module ActiveRecord
|
|
25
25
|
self.name
|
26
26
|
end
|
27
27
|
|
28
|
+
foreign_key = has_many_association.foreign_key.to_s
|
28
29
|
child_class = has_many_association.klass
|
29
30
|
belongs_to = child_class.reflect_on_all_associations(:belongs_to)
|
30
|
-
reflection = belongs_to.find { |e| e.
|
31
|
+
reflection = belongs_to.find { |e| e.foreign_key.to_s == foreign_key }
|
31
32
|
counter_name = reflection.counter_cache_column
|
32
33
|
|
33
34
|
stmt = unscoped.where(arel_table[primary_key].eq(object.id)).arel.compile_update({
|
@@ -38,6 +38,18 @@ module ActiveRecord
|
|
38
38
|
# account2.save!
|
39
39
|
# end
|
40
40
|
#
|
41
|
+
# You can start a transaction and acquire the lock in one go by calling
|
42
|
+
# <tt>with_lock</tt> with a block. The block is called from within
|
43
|
+
# a transaction, the object is already locked. Example:
|
44
|
+
#
|
45
|
+
# account = Account.first
|
46
|
+
# account.with_lock do
|
47
|
+
# # This block is called within a transaction,
|
48
|
+
# # account is already locked.
|
49
|
+
# account.balance -= 100
|
50
|
+
# account.save!
|
51
|
+
# end
|
52
|
+
#
|
41
53
|
# Database-specific information on row locking:
|
42
54
|
# MySQL: http://dev.mysql.com/doc/refman/5.1/en/innodb-locking-reads.html
|
43
55
|
# PostgreSQL: http://www.postgresql.org/docs/current/interactive/sql-select.html#SQL-FOR-UPDATE-SHARE
|
@@ -50,6 +62,16 @@ module ActiveRecord
|
|
50
62
|
reload(:lock => lock) if persisted?
|
51
63
|
self
|
52
64
|
end
|
65
|
+
|
66
|
+
# Wraps the passed block in a transaction, locking the object
|
67
|
+
# before yielding. You pass can the SQL locking clause
|
68
|
+
# as argument (see <tt>lock!</tt>).
|
69
|
+
def with_lock(lock = true)
|
70
|
+
transaction do
|
71
|
+
lock!(lock)
|
72
|
+
yield
|
73
|
+
end
|
74
|
+
end
|
53
75
|
end
|
54
76
|
end
|
55
77
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require "active_support/core_ext/module/delegation"
|
2
2
|
require "active_support/core_ext/class/attribute_accessors"
|
3
3
|
require "active_support/core_ext/array/wrap"
|
4
|
+
require 'active_support/deprecation'
|
4
5
|
|
5
6
|
module ActiveRecord
|
6
7
|
# Exception that can be raised to stop migrations from going backwards.
|
@@ -508,7 +509,7 @@ module ActiveRecord
|
|
508
509
|
File.basename(filename)
|
509
510
|
end
|
510
511
|
|
511
|
-
delegate :migrate, :announce, :write, :to
|
512
|
+
delegate :migrate, :announce, :write, :to => :migration
|
512
513
|
|
513
514
|
private
|
514
515
|
|
@@ -594,7 +595,14 @@ module ActiveRecord
|
|
594
595
|
migrations_paths.first
|
595
596
|
end
|
596
597
|
|
597
|
-
def migrations(paths,
|
598
|
+
def migrations(paths, *args)
|
599
|
+
if args.empty?
|
600
|
+
subdirectories = true
|
601
|
+
else
|
602
|
+
subdirectories = args.first
|
603
|
+
ActiveSupport::Deprecation.warn "The `subdirectories` argument to `migrations` is deprecated"
|
604
|
+
end
|
605
|
+
|
598
606
|
paths = Array.wrap(paths)
|
599
607
|
|
600
608
|
glob = subdirectories ? "**/" : ""
|
@@ -139,10 +139,14 @@ module ActiveRecord
|
|
139
139
|
|
140
140
|
# Computes the table name, (re)sets it internally, and returns it.
|
141
141
|
def reset_table_name #:nodoc:
|
142
|
-
if
|
142
|
+
if abstract_class?
|
143
|
+
self.table_name = if superclass == Base || superclass.abstract_class?
|
144
|
+
nil
|
145
|
+
else
|
146
|
+
superclass.table_name
|
147
|
+
end
|
148
|
+
elsif superclass.abstract_class?
|
143
149
|
self.table_name = superclass.table_name || compute_table_name
|
144
|
-
elsif abstract_class?
|
145
|
-
self.table_name = superclass == Base ? nil : superclass.table_name
|
146
150
|
else
|
147
151
|
self.table_name = compute_table_name
|
148
152
|
end
|
@@ -57,9 +57,9 @@ module ActiveRecord
|
|
57
57
|
# array, it actually returns a relation object and can have other query
|
58
58
|
# methods appended to it, such as the other methods in ActiveRecord::QueryMethods.
|
59
59
|
#
|
60
|
-
#
|
60
|
+
# The argument to the method can also be an array of fields.
|
61
61
|
#
|
62
|
-
# >> Model.select(:field, :other_field, :and_one_more)
|
62
|
+
# >> Model.select([:field, :other_field, :and_one_more])
|
63
63
|
# => [#<Model field: "value", other_field: "value", and_one_more: "value">]
|
64
64
|
#
|
65
65
|
# Any attributes that do not have fields retrieved by a select
|
@@ -93,6 +93,16 @@ module ActiveRecord
|
|
93
93
|
relation
|
94
94
|
end
|
95
95
|
|
96
|
+
# Replaces any existing order defined on the relation with the specified order.
|
97
|
+
#
|
98
|
+
# User.order('email DESC').reorder('id ASC') # generated SQL has 'ORDER BY id ASC'
|
99
|
+
#
|
100
|
+
# Subsequent calls to order on the same relation will be appended. For example:
|
101
|
+
#
|
102
|
+
# User.order('email DESC').reorder('id ASC').order('name ASC')
|
103
|
+
#
|
104
|
+
# generates a query with 'ORDER BY id ASC, name ASC'.
|
105
|
+
#
|
96
106
|
def reorder(*args)
|
97
107
|
return self if args.blank?
|
98
108
|
|
metadata
CHANGED
@@ -1,100 +1,69 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
6
|
-
segments:
|
7
|
-
- 3
|
8
|
-
- 2
|
9
|
-
- 0
|
10
|
-
- rc2
|
11
|
-
version: 3.2.0.rc2
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 3.2.0
|
5
|
+
prerelease:
|
12
6
|
platform: ruby
|
13
|
-
authors:
|
7
|
+
authors:
|
14
8
|
- David Heinemeier Hansson
|
15
9
|
autorequire:
|
16
10
|
bindir: bin
|
17
11
|
cert_chain: []
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
dependencies:
|
22
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2012-01-20 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
23
15
|
name: activesupport
|
24
|
-
|
25
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
16
|
+
requirement: &70230647834700 !ruby/object:Gem::Requirement
|
26
17
|
none: false
|
27
|
-
requirements:
|
28
|
-
- -
|
29
|
-
- !ruby/object:Gem::Version
|
30
|
-
|
31
|
-
segments:
|
32
|
-
- 3
|
33
|
-
- 2
|
34
|
-
- 0
|
35
|
-
- rc2
|
36
|
-
version: 3.2.0.rc2
|
18
|
+
requirements:
|
19
|
+
- - =
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 3.2.0
|
37
22
|
type: :runtime
|
38
|
-
version_requirements: *id001
|
39
|
-
- !ruby/object:Gem::Dependency
|
40
|
-
name: activemodel
|
41
23
|
prerelease: false
|
42
|
-
|
24
|
+
version_requirements: *70230647834700
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: activemodel
|
27
|
+
requirement: &70230647834260 !ruby/object:Gem::Requirement
|
43
28
|
none: false
|
44
|
-
requirements:
|
45
|
-
- -
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
|
48
|
-
segments:
|
49
|
-
- 3
|
50
|
-
- 2
|
51
|
-
- 0
|
52
|
-
- rc2
|
53
|
-
version: 3.2.0.rc2
|
29
|
+
requirements:
|
30
|
+
- - =
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 3.2.0
|
54
33
|
type: :runtime
|
55
|
-
version_requirements: *id002
|
56
|
-
- !ruby/object:Gem::Dependency
|
57
|
-
name: arel
|
58
34
|
prerelease: false
|
59
|
-
|
35
|
+
version_requirements: *70230647834260
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: arel
|
38
|
+
requirement: &70230647833760 !ruby/object:Gem::Requirement
|
60
39
|
none: false
|
61
|
-
requirements:
|
40
|
+
requirements:
|
62
41
|
- - ~>
|
63
|
-
- !ruby/object:Gem::Version
|
64
|
-
|
65
|
-
segments:
|
66
|
-
- 3
|
67
|
-
- 0
|
68
|
-
- 0
|
69
|
-
- rc1
|
70
|
-
version: 3.0.0.rc1
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 3.0.0
|
71
44
|
type: :runtime
|
72
|
-
version_requirements: *id003
|
73
|
-
- !ruby/object:Gem::Dependency
|
74
|
-
name: tzinfo
|
75
45
|
prerelease: false
|
76
|
-
|
46
|
+
version_requirements: *70230647833760
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: tzinfo
|
49
|
+
requirement: &70230647833280 !ruby/object:Gem::Requirement
|
77
50
|
none: false
|
78
|
-
requirements:
|
51
|
+
requirements:
|
79
52
|
- - ~>
|
80
|
-
- !ruby/object:Gem::Version
|
81
|
-
hash: 41
|
82
|
-
segments:
|
83
|
-
- 0
|
84
|
-
- 3
|
85
|
-
- 29
|
53
|
+
- !ruby/object:Gem::Version
|
86
54
|
version: 0.3.29
|
87
55
|
type: :runtime
|
88
|
-
|
89
|
-
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70230647833280
|
58
|
+
description: Databases on Rails. Build a persistent domain model by mapping database
|
59
|
+
tables to Ruby classes. Strong conventions for associations, validations, aggregations,
|
60
|
+
migrations, and testing come baked-in.
|
90
61
|
email: david@loudthinking.com
|
91
62
|
executables: []
|
92
|
-
|
93
63
|
extensions: []
|
94
|
-
|
95
|
-
extra_rdoc_files:
|
64
|
+
extra_rdoc_files:
|
96
65
|
- README.rdoc
|
97
|
-
files:
|
66
|
+
files:
|
98
67
|
- CHANGELOG.md
|
99
68
|
- MIT-LICENSE
|
100
69
|
- README.rdoc
|
@@ -244,44 +213,30 @@ files:
|
|
244
213
|
- lib/rails/generators/active_record/session_migration/session_migration_generator.rb
|
245
214
|
- lib/rails/generators/active_record/session_migration/templates/migration.rb
|
246
215
|
- lib/rails/generators/active_record.rb
|
247
|
-
has_rdoc: true
|
248
216
|
homepage: http://www.rubyonrails.org
|
249
217
|
licenses: []
|
250
|
-
|
251
218
|
post_install_message:
|
252
|
-
rdoc_options:
|
219
|
+
rdoc_options:
|
253
220
|
- --main
|
254
221
|
- README.rdoc
|
255
|
-
require_paths:
|
222
|
+
require_paths:
|
256
223
|
- lib
|
257
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
224
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
258
225
|
none: false
|
259
|
-
requirements:
|
260
|
-
- -
|
261
|
-
- !ruby/object:Gem::Version
|
262
|
-
hash: 57
|
263
|
-
segments:
|
264
|
-
- 1
|
265
|
-
- 8
|
266
|
-
- 7
|
226
|
+
requirements:
|
227
|
+
- - ! '>='
|
228
|
+
- !ruby/object:Gem::Version
|
267
229
|
version: 1.8.7
|
268
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
230
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
269
231
|
none: false
|
270
|
-
requirements:
|
271
|
-
- -
|
272
|
-
- !ruby/object:Gem::Version
|
273
|
-
|
274
|
-
segments:
|
275
|
-
- 1
|
276
|
-
- 3
|
277
|
-
- 1
|
278
|
-
version: 1.3.1
|
232
|
+
requirements:
|
233
|
+
- - ! '>='
|
234
|
+
- !ruby/object:Gem::Version
|
235
|
+
version: '0'
|
279
236
|
requirements: []
|
280
|
-
|
281
237
|
rubyforge_project:
|
282
|
-
rubygems_version: 1.
|
238
|
+
rubygems_version: 1.8.10
|
283
239
|
signing_key:
|
284
240
|
specification_version: 3
|
285
241
|
summary: Object-relational mapper framework (part of Rails).
|
286
242
|
test_files: []
|
287
|
-
|