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.

@@ -1,4 +1,34 @@
1
- ## Rails 3.2.0 (unreleased) ##
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
- *Piotr Sarnacki*
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
- alias [] read_attribute
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
- alias []= write_attribute
29
-
30
- public :[], :[]=
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
- return if attribute_methods_generated?
38
- superclass.define_attribute_methods unless self == base_class
39
- super(column_names)
40
- @attribute_methods_generated = true
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.class_name == expected_name }
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=>:migration
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, subdirectories = true)
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 superclass.abstract_class?
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
@@ -1,5 +1,5 @@
1
1
  #FIXME Remove if ArJdbcMysql will give.
2
- module ArJdbcMySQL
2
+ module ArJdbcMySQL #:nodoc:
3
3
  class Error < StandardError
4
4
  attr_accessor :error_number, :sql_state
5
5
 
@@ -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
- # This method will also take multiple parameters:
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
 
@@ -3,7 +3,7 @@ module ActiveRecord
3
3
  MAJOR = 3
4
4
  MINOR = 2
5
5
  TINY = 0
6
- PRE = "rc2"
6
+ PRE = nil
7
7
 
8
8
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
9
9
  end
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
- hash: 977940591
5
- prerelease: true
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
- date: 2012-01-04 00:00:00 -02:00
20
- default_executable:
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
- prerelease: false
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
- hash: 977940591
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
- requirement: &id002 !ruby/object:Gem::Requirement
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
- hash: 977940591
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
- requirement: &id003 !ruby/object:Gem::Requirement
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
- hash: 977940606
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
- requirement: &id004 !ruby/object:Gem::Requirement
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
- version_requirements: *id004
89
- 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.
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
- hash: 25
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.3.7
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
-