activerecord 3.1.0.rc5 → 3.1.0.rc6
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 +6 -0
- data/README.rdoc +1 -1
- data/lib/active_record/associations.rb +6 -0
- data/lib/active_record/associations/association.rb +8 -8
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +5 -5
- data/lib/active_record/associations/collection_association.rb +24 -43
- data/lib/active_record/associations/collection_proxy.rb +19 -12
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +2 -2
- data/lib/active_record/associations/join_dependency.rb +2 -3
- data/lib/active_record/associations/preloader/has_and_belongs_to_many.rb +1 -1
- data/lib/active_record/attribute_methods/primary_key.rb +2 -3
- data/lib/active_record/base.rb +36 -44
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +15 -4
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +33 -14
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +3 -2
- data/lib/active_record/connection_adapters/abstract_adapter.rb +22 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +26 -1
- data/lib/active_record/connection_adapters/mysql_adapter.rb +26 -1
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +4 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +2 -0
- data/lib/active_record/connection_adapters/sqlite_adapter.rb +5 -1
- data/lib/active_record/counter_cache.rb +1 -1
- data/lib/active_record/locking/optimistic.rb +2 -2
- data/lib/active_record/migration.rb +7 -3
- data/lib/active_record/observer.rb +1 -1
- data/lib/active_record/persistence.rb +1 -1
- data/lib/active_record/railties/databases.rake +2 -1
- data/lib/active_record/relation.rb +17 -12
- data/lib/active_record/relation/calculations.rb +2 -2
- data/lib/active_record/relation/finder_methods.rb +2 -2
- data/lib/active_record/schema_dumper.rb +4 -0
- data/lib/active_record/validations/associated.rb +1 -9
- data/lib/active_record/version.rb +1 -1
- metadata +27 -13
data/CHANGELOG
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
*Rails 3.1.0 (unreleased)*
|
2
2
|
|
3
|
+
* Add a proxy_association method to association proxies, which can be called by association
|
4
|
+
extensions to access information about the association. This replaces proxy_owner etc with
|
5
|
+
proxy_association.owner.
|
6
|
+
|
7
|
+
[Jon Leighton]
|
8
|
+
|
3
9
|
* Active Record's dynamic finder will now show a deprecation warning if you passing in less number of arguments than what you call in method signature. This behavior will raise ArgumentError in the next version of Rails [Prem Sichanugrist]
|
4
10
|
|
5
11
|
* Deprecated the AssociationCollection constant. CollectionProxy is now the appropriate constant
|
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/master/activerecord
|
206
|
+
* https://github.com/rails/rails/tree/master/activerecord
|
207
207
|
|
208
208
|
|
209
209
|
== License
|
@@ -467,6 +467,12 @@ module ActiveRecord
|
|
467
467
|
# * <tt>record.association(:items).target</tt> - Returns the associated object for +belongs_to+ and +has_one+, or
|
468
468
|
# the collection of associated objects for +has_many+ and +has_and_belongs_to_many+.
|
469
469
|
#
|
470
|
+
# However, inside the actual extension code, you will not have access to the <tt>record</tt> as
|
471
|
+
# above. In this case, you can access <tt>proxy_association</tt>. For example,
|
472
|
+
# <tt>record.association(:items)</tt> and <tt>record.items.proxy_association</tt> will return
|
473
|
+
# the same object, allowing you to make calls like <tt>proxy_association.owner</tt> inside
|
474
|
+
# association extensions.
|
475
|
+
#
|
470
476
|
# === Association Join Models
|
471
477
|
#
|
472
478
|
# Has Many associations can be configured with the <tt>:through</tt> option to use an
|
@@ -152,20 +152,20 @@ module ActiveRecord
|
|
152
152
|
reset
|
153
153
|
end
|
154
154
|
|
155
|
+
def interpolate(sql, record = nil)
|
156
|
+
if sql.respond_to?(:to_proc)
|
157
|
+
owner.send(:instance_exec, record, &sql)
|
158
|
+
else
|
159
|
+
sql
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
155
163
|
private
|
156
164
|
|
157
165
|
def find_target?
|
158
166
|
!loaded? && (!owner.new_record? || foreign_key_present?) && klass
|
159
167
|
end
|
160
168
|
|
161
|
-
def interpolate(sql, record = nil)
|
162
|
-
if sql.respond_to?(:to_proc)
|
163
|
-
owner.send(:instance_exec, record, &sql)
|
164
|
-
else
|
165
|
-
sql
|
166
|
-
end
|
167
|
-
end
|
168
|
-
|
169
169
|
def creation_attributes
|
170
170
|
attributes = {}
|
171
171
|
|
@@ -2,6 +2,11 @@ module ActiveRecord
|
|
2
2
|
# = Active Record Belongs To Polymorphic Association
|
3
3
|
module Associations
|
4
4
|
class BelongsToPolymorphicAssociation < BelongsToAssociation #:nodoc:
|
5
|
+
def klass
|
6
|
+
type = owner[reflection.foreign_type]
|
7
|
+
type.presence && type.constantize
|
8
|
+
end
|
9
|
+
|
5
10
|
private
|
6
11
|
|
7
12
|
def replace_keys(record)
|
@@ -17,11 +22,6 @@ module ActiveRecord
|
|
17
22
|
reflection.polymorphic_inverse_of(record.class)
|
18
23
|
end
|
19
24
|
|
20
|
-
def klass
|
21
|
-
type = owner[reflection.foreign_type]
|
22
|
-
type.presence && type.constantize
|
23
|
-
end
|
24
|
-
|
25
25
|
def raise_on_type_mismatch(record)
|
26
26
|
# A polymorphic association cannot have a type mismatch, by definition
|
27
27
|
end
|
@@ -114,13 +114,19 @@ module ActiveRecord
|
|
114
114
|
# Add +records+ to this association. Returns +self+ so method calls may be chained.
|
115
115
|
# Since << flattens its argument list and inserts each record, +push+ and +concat+ behave identically.
|
116
116
|
def concat(*records)
|
117
|
+
result = true
|
117
118
|
load_target if owner.new_record?
|
118
119
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
120
|
+
transaction do
|
121
|
+
records.flatten.each do |record|
|
122
|
+
raise_on_type_mismatch(record)
|
123
|
+
add_to_target(record) do |r|
|
124
|
+
result &&= insert_record(record) unless owner.new_record?
|
125
|
+
end
|
126
|
+
end
|
123
127
|
end
|
128
|
+
|
129
|
+
result && records
|
124
130
|
end
|
125
131
|
|
126
132
|
# Starts a transaction in the association class's database connection.
|
@@ -289,10 +295,14 @@ module ActiveRecord
|
|
289
295
|
other_array.each { |val| raise_on_type_mismatch(val) }
|
290
296
|
original_target = load_target.dup
|
291
297
|
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
298
|
+
transaction do
|
299
|
+
delete(target - other_array)
|
300
|
+
|
301
|
+
unless concat(other_array - target)
|
302
|
+
@target = original_target
|
303
|
+
raise RecordNotSaved, "Failed to replace #{reflection.name} because one or more of the " \
|
304
|
+
"new records could not be saved."
|
305
|
+
end
|
296
306
|
end
|
297
307
|
end
|
298
308
|
|
@@ -428,20 +438,14 @@ module ActiveRecord
|
|
428
438
|
records.each { |record| raise_on_type_mismatch(record) }
|
429
439
|
existing_records = records.reject { |r| r.new_record? }
|
430
440
|
|
431
|
-
|
432
|
-
|
433
|
-
else
|
434
|
-
transaction { remove_records(existing_records, records, method) }
|
435
|
-
end
|
436
|
-
end
|
437
|
-
|
438
|
-
def remove_records(existing_records, records, method)
|
439
|
-
records.each { |record| callback(:before_remove, record) }
|
441
|
+
transaction do
|
442
|
+
records.each { |record| callback(:before_remove, record) }
|
440
443
|
|
441
|
-
|
442
|
-
|
444
|
+
delete_records(existing_records, method) if existing_records.any?
|
445
|
+
records.each { |record| target.delete(record) }
|
443
446
|
|
444
|
-
|
447
|
+
records.each { |record| callback(:after_remove, record) }
|
448
|
+
end
|
445
449
|
end
|
446
450
|
|
447
451
|
# Delete the given records from the association, using one of the methods :destroy,
|
@@ -450,29 +454,6 @@ module ActiveRecord
|
|
450
454
|
raise NotImplementedError
|
451
455
|
end
|
452
456
|
|
453
|
-
def replace_records(new_target, original_target)
|
454
|
-
delete(target - new_target)
|
455
|
-
|
456
|
-
unless concat(new_target - target)
|
457
|
-
@target = original_target
|
458
|
-
raise RecordNotSaved, "Failed to replace #{reflection.name} because one or more of the " \
|
459
|
-
"new records could not be saved."
|
460
|
-
end
|
461
|
-
end
|
462
|
-
|
463
|
-
def concat_records(records)
|
464
|
-
result = true
|
465
|
-
|
466
|
-
records.flatten.each do |record|
|
467
|
-
raise_on_type_mismatch(record)
|
468
|
-
add_to_target(record) do |r|
|
469
|
-
result &&= insert_record(record) unless owner.new_record?
|
470
|
-
end
|
471
|
-
end
|
472
|
-
|
473
|
-
result && records
|
474
|
-
end
|
475
|
-
|
476
457
|
def callback(method, record)
|
477
458
|
callbacks_for(method).each do |callback|
|
478
459
|
case callback
|
@@ -65,23 +65,27 @@ module ActiveRecord
|
|
65
65
|
|
66
66
|
alias_method :new, :build
|
67
67
|
|
68
|
+
def proxy_association
|
69
|
+
@association
|
70
|
+
end
|
71
|
+
|
68
72
|
def respond_to?(name, include_private = false)
|
69
73
|
super ||
|
70
74
|
(load_target && target.respond_to?(name, include_private)) ||
|
71
|
-
|
75
|
+
proxy_association.klass.respond_to?(name, include_private)
|
72
76
|
end
|
73
77
|
|
74
78
|
def method_missing(method, *args, &block)
|
75
79
|
match = DynamicFinderMatch.match(method)
|
76
80
|
if match && match.instantiator?
|
77
81
|
record = send(:find_or_instantiator_by_attributes, match, match.attribute_names, *args) do |r|
|
78
|
-
|
79
|
-
|
82
|
+
proxy_association.send :set_owner_attributes, r
|
83
|
+
proxy_association.send :add_to_target, r
|
80
84
|
yield(r) if block_given?
|
81
85
|
end
|
82
86
|
end
|
83
87
|
|
84
|
-
if target.respond_to?(method) || (
|
88
|
+
if target.respond_to?(method) || (!proxy_association.klass.respond_to?(method) && Class.respond_to?(method))
|
85
89
|
if load_target
|
86
90
|
if target.respond_to?(method)
|
87
91
|
target.send(method, *args, &block)
|
@@ -111,7 +115,7 @@ module ActiveRecord
|
|
111
115
|
alias_method :to_a, :to_ary
|
112
116
|
|
113
117
|
def <<(*records)
|
114
|
-
|
118
|
+
proxy_association.concat(records) && self
|
115
119
|
end
|
116
120
|
alias_method :push, :<<
|
117
121
|
|
@@ -121,32 +125,35 @@ module ActiveRecord
|
|
121
125
|
end
|
122
126
|
|
123
127
|
def reload
|
124
|
-
|
128
|
+
proxy_association.reload
|
125
129
|
self
|
126
130
|
end
|
127
131
|
|
128
132
|
def proxy_owner
|
129
133
|
ActiveSupport::Deprecation.warn(
|
130
134
|
"Calling record.#{@association.reflection.name}.proxy_owner is deprecated. Please use " \
|
131
|
-
"record.association(:#{@association.reflection.name}).owner instead."
|
135
|
+
"record.association(:#{@association.reflection.name}).owner instead. Or, from an " \
|
136
|
+
"association extension you can access proxy_association.owner."
|
132
137
|
)
|
133
|
-
|
138
|
+
proxy_association.owner
|
134
139
|
end
|
135
140
|
|
136
141
|
def proxy_target
|
137
142
|
ActiveSupport::Deprecation.warn(
|
138
143
|
"Calling record.#{@association.reflection.name}.proxy_target is deprecated. Please use " \
|
139
|
-
"record.association(:#{@association.reflection.name}).target instead."
|
144
|
+
"record.association(:#{@association.reflection.name}).target instead. Or, from an " \
|
145
|
+
"association extension you can access proxy_association.target."
|
140
146
|
)
|
141
|
-
|
147
|
+
proxy_association.target
|
142
148
|
end
|
143
149
|
|
144
150
|
def proxy_reflection
|
145
151
|
ActiveSupport::Deprecation.warn(
|
146
152
|
"Calling record.#{@association.reflection.name}.proxy_reflection is deprecated. Please use " \
|
147
|
-
"record.association(:#{@association.reflection.name}).reflection instead."
|
153
|
+
"record.association(:#{@association.reflection.name}).reflection instead. Or, from an " \
|
154
|
+
"association extension you can access proxy_association.reflection."
|
148
155
|
)
|
149
|
-
|
156
|
+
proxy_association.reflection
|
150
157
|
end
|
151
158
|
end
|
152
159
|
end
|
@@ -26,7 +26,7 @@ module ActiveRecord
|
|
26
26
|
join_table[reflection.association_foreign_key] => record.id
|
27
27
|
)
|
28
28
|
|
29
|
-
owner.connection.insert stmt
|
29
|
+
owner.connection.insert stmt
|
30
30
|
end
|
31
31
|
|
32
32
|
record
|
@@ -46,7 +46,7 @@ module ActiveRecord
|
|
46
46
|
stmt = relation.where(relation[reflection.foreign_key].eq(owner.id).
|
47
47
|
and(relation[reflection.association_foreign_key].in(records.map { |x| x.id }.compact))
|
48
48
|
).compile_delete
|
49
|
-
owner.connection.delete stmt
|
49
|
+
owner.connection.delete stmt
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
@@ -188,13 +188,12 @@ module ActiveRecord
|
|
188
188
|
association = join_part.instantiate(row) unless row[join_part.aliased_primary_key].nil?
|
189
189
|
set_target_and_inverse(join_part, association, record)
|
190
190
|
else
|
191
|
-
|
192
|
-
association = join_part.instantiate(row)
|
191
|
+
association = join_part.instantiate(row) unless row[join_part.aliased_primary_key].nil?
|
193
192
|
case macro
|
194
193
|
when :has_many, :has_and_belongs_to_many
|
195
194
|
other = record.association(join_part.reflection.name)
|
196
195
|
other.loaded!
|
197
|
-
other.target.push(association)
|
196
|
+
other.target.push(association) if association
|
198
197
|
other.set_inverse_instance(association)
|
199
198
|
when :belongs_to
|
200
199
|
set_target_and_inverse(join_part, association, record)
|
@@ -13,7 +13,7 @@ module ActiveRecord
|
|
13
13
|
# access the aliased column on the join table
|
14
14
|
def records_for(ids)
|
15
15
|
scope = super
|
16
|
-
klass.connection.select_all(scope.arel
|
16
|
+
klass.connection.select_all(scope.arel, 'SQL', scope.bind_values)
|
17
17
|
end
|
18
18
|
|
19
19
|
def owner_key_name
|
@@ -3,11 +3,10 @@ module ActiveRecord
|
|
3
3
|
module PrimaryKey
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
|
-
# Returns this record's primary key value wrapped in an Array
|
7
|
-
# the record is not persisted? or has just been destroyed.
|
6
|
+
# Returns this record's primary key value wrapped in an Array if one is available
|
8
7
|
def to_key
|
9
8
|
key = send(self.class.primary_key)
|
10
|
-
|
9
|
+
[key] if key
|
11
10
|
end
|
12
11
|
|
13
12
|
module ClassMethods
|
data/lib/active_record/base.rb
CHANGED
@@ -940,17 +940,6 @@ module ActiveRecord #:nodoc:
|
|
940
940
|
self.current_scope = nil
|
941
941
|
end
|
942
942
|
|
943
|
-
# Specifies how the record is loaded by +Marshal+.
|
944
|
-
#
|
945
|
-
# +_load+ sets an instance variable for each key in the hash it takes as input.
|
946
|
-
# Override this method if you require more complex marshalling.
|
947
|
-
def _load(data)
|
948
|
-
record = allocate
|
949
|
-
record.init_with(Marshal.load(data))
|
950
|
-
record
|
951
|
-
end
|
952
|
-
|
953
|
-
|
954
943
|
# Finder methods must instantiate through this method to work with the
|
955
944
|
# single-table inheritance model that makes it possible to create
|
956
945
|
# objects of different types from the same table.
|
@@ -1057,12 +1046,10 @@ module ActiveRecord #:nodoc:
|
|
1057
1046
|
if match = DynamicFinderMatch.match(method_id)
|
1058
1047
|
attribute_names = match.attribute_names
|
1059
1048
|
super unless all_attributes_exists?(attribute_names)
|
1060
|
-
if arguments.size < attribute_names.size
|
1061
|
-
ActiveSupport::Deprecation.warn(
|
1062
|
-
|
1063
|
-
|
1064
|
-
"Please passing `nil' to the argument you want it to be nil."
|
1065
|
-
)
|
1049
|
+
if !arguments.first.is_a?(Hash) && arguments.size < attribute_names.size
|
1050
|
+
ActiveSupport::Deprecation.warn(<<-eowarn)
|
1051
|
+
Calling dynamic finder with less number of arguments than the number of attributes in method name is deprecated and will raise an ArguementError in the next version of Rails. Please passing `nil' to the argument you want it to be nil.
|
1052
|
+
eowarn
|
1066
1053
|
end
|
1067
1054
|
if match.finder?
|
1068
1055
|
options = arguments.extract_options!
|
@@ -1283,27 +1270,43 @@ MSG
|
|
1283
1270
|
self.default_scopes = default_scopes + [scope]
|
1284
1271
|
end
|
1285
1272
|
|
1286
|
-
# The @ignore_default_scope flag is used to prevent an infinite recursion situation where
|
1287
|
-
# a default scope references a scope which has a default scope which references a scope...
|
1288
1273
|
def build_default_scope #:nodoc:
|
1289
|
-
return if defined?(@ignore_default_scope) && @ignore_default_scope
|
1290
|
-
@ignore_default_scope = true
|
1291
|
-
|
1292
1274
|
if method(:default_scope).owner != Base.singleton_class
|
1293
|
-
default_scope
|
1275
|
+
evaluate_default_scope { default_scope }
|
1294
1276
|
elsif default_scopes.any?
|
1295
|
-
|
1296
|
-
|
1297
|
-
|
1298
|
-
|
1299
|
-
|
1300
|
-
|
1301
|
-
|
1277
|
+
evaluate_default_scope do
|
1278
|
+
default_scopes.inject(relation) do |default_scope, scope|
|
1279
|
+
if scope.is_a?(Hash)
|
1280
|
+
default_scope.apply_finder_options(scope)
|
1281
|
+
elsif !scope.is_a?(Relation) && scope.respond_to?(:call)
|
1282
|
+
default_scope.merge(scope.call)
|
1283
|
+
else
|
1284
|
+
default_scope.merge(scope)
|
1285
|
+
end
|
1302
1286
|
end
|
1303
1287
|
end
|
1304
1288
|
end
|
1305
|
-
|
1306
|
-
|
1289
|
+
end
|
1290
|
+
|
1291
|
+
def ignore_default_scope? #:nodoc:
|
1292
|
+
Thread.current["#{self}_ignore_default_scope"]
|
1293
|
+
end
|
1294
|
+
|
1295
|
+
def ignore_default_scope=(ignore) #:nodoc:
|
1296
|
+
Thread.current["#{self}_ignore_default_scope"] = ignore
|
1297
|
+
end
|
1298
|
+
|
1299
|
+
# The ignore_default_scope flag is used to prevent an infinite recursion situation where
|
1300
|
+
# a default scope references a scope which has a default scope which references a scope...
|
1301
|
+
def evaluate_default_scope
|
1302
|
+
return if ignore_default_scope?
|
1303
|
+
|
1304
|
+
begin
|
1305
|
+
self.ignore_default_scope = true
|
1306
|
+
yield
|
1307
|
+
ensure
|
1308
|
+
self.ignore_default_scope = false
|
1309
|
+
end
|
1307
1310
|
end
|
1308
1311
|
|
1309
1312
|
# Returns the class type of the record using the current module as a prefix. So descendants of
|
@@ -1425,9 +1428,8 @@ MSG
|
|
1425
1428
|
attrs = expand_hash_conditions_for_aggregates(attrs)
|
1426
1429
|
|
1427
1430
|
table = Arel::Table.new(table_name).alias(default_table_name)
|
1428
|
-
viz = Arel::Visitors.for(arel_engine)
|
1429
1431
|
PredicateBuilder.build_from_hash(arel_engine, attrs, table).map { |b|
|
1430
|
-
|
1432
|
+
connection.visitor.accept b
|
1431
1433
|
}.join(' AND ')
|
1432
1434
|
end
|
1433
1435
|
alias_method :sanitize_sql_hash, :sanitize_sql_hash_for_conditions
|
@@ -1605,16 +1607,6 @@ MSG
|
|
1605
1607
|
self
|
1606
1608
|
end
|
1607
1609
|
|
1608
|
-
# Specifies how the record is dumped by +Marshal+.
|
1609
|
-
#
|
1610
|
-
# +_dump+ emits a marshalled hash which has been passed to +encode_with+. Override this
|
1611
|
-
# method if you require more complex marshalling.
|
1612
|
-
def _dump(level)
|
1613
|
-
dump = {}
|
1614
|
-
encode_with(dump)
|
1615
|
-
Marshal.dump(dump)
|
1616
|
-
end
|
1617
|
-
|
1618
1610
|
# Returns a String, which Action Pack uses for constructing an URL to this
|
1619
1611
|
# object. The default implementation returns this record's id as a String,
|
1620
1612
|
# or nil if this record's unsaved.
|
@@ -82,10 +82,11 @@ module ActiveRecord
|
|
82
82
|
# default max pool size to 5
|
83
83
|
@size = (spec.config[:pool] && spec.config[:pool].to_i) || 5
|
84
84
|
|
85
|
-
@connections
|
86
|
-
@checked_out
|
85
|
+
@connections = []
|
86
|
+
@checked_out = []
|
87
87
|
@automatic_reconnect = true
|
88
|
-
@tables
|
88
|
+
@tables = {}
|
89
|
+
@visitor = nil
|
89
90
|
|
90
91
|
@columns = Hash.new do |h, table_name|
|
91
92
|
h[table_name] = with_connection do |conn|
|
@@ -298,8 +299,18 @@ module ActiveRecord
|
|
298
299
|
:connected?, :disconnect!, :with => :@connection_mutex
|
299
300
|
|
300
301
|
private
|
302
|
+
|
301
303
|
def new_connection
|
302
|
-
ActiveRecord::Base.send(spec.adapter_method, spec.config)
|
304
|
+
connection = ActiveRecord::Base.send(spec.adapter_method, spec.config)
|
305
|
+
|
306
|
+
# TODO: This is a bit icky, and in the long term we may want to change the method
|
307
|
+
# signature for connections. Also, if we switch to have one visitor per
|
308
|
+
# connection (and therefore per thread), we can get rid of the thread-local
|
309
|
+
# variable in Arel::Visitors::ToSql.
|
310
|
+
@visitor ||= connection.class.visitor_for(self)
|
311
|
+
connection.visitor = @visitor
|
312
|
+
|
313
|
+
connection
|
303
314
|
end
|
304
315
|
|
305
316
|
def current_connection_id #:nodoc:
|
@@ -3,30 +3,39 @@ require 'active_support/core_ext/module/deprecation'
|
|
3
3
|
module ActiveRecord
|
4
4
|
module ConnectionAdapters # :nodoc:
|
5
5
|
module DatabaseStatements
|
6
|
+
# Converts an arel AST to SQL
|
7
|
+
def to_sql(arel)
|
8
|
+
if arel.respond_to?(:ast)
|
9
|
+
visitor.accept(arel.ast)
|
10
|
+
else
|
11
|
+
arel
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
6
15
|
# Returns an array of record hashes with the column names as keys and
|
7
16
|
# column values as values.
|
8
|
-
def select_all(
|
9
|
-
select(
|
17
|
+
def select_all(arel, name = nil, binds = [])
|
18
|
+
select(to_sql(arel), name, binds)
|
10
19
|
end
|
11
20
|
|
12
21
|
# Returns a record hash with the column names as keys and column values
|
13
22
|
# as values.
|
14
|
-
def select_one(
|
15
|
-
result = select_all(
|
23
|
+
def select_one(arel, name = nil)
|
24
|
+
result = select_all(arel, name)
|
16
25
|
result.first if result
|
17
26
|
end
|
18
27
|
|
19
28
|
# Returns a single value from a record
|
20
|
-
def select_value(
|
21
|
-
if result = select_one(
|
29
|
+
def select_value(arel, name = nil)
|
30
|
+
if result = select_one(arel, name)
|
22
31
|
result.values.first
|
23
32
|
end
|
24
33
|
end
|
25
34
|
|
26
35
|
# Returns an array of the values of the first column in a select:
|
27
36
|
# select_values("SELECT id FROM companies LIMIT 3") => [1,2,3]
|
28
|
-
def select_values(
|
29
|
-
result = select_rows(
|
37
|
+
def select_values(arel, name = nil)
|
38
|
+
result = select_rows(to_sql(arel), name)
|
30
39
|
result.map { |v| v[0] }
|
31
40
|
end
|
32
41
|
|
@@ -76,20 +85,20 @@ module ActiveRecord
|
|
76
85
|
#
|
77
86
|
# If the next id was calculated in advance (as in Oracle), it should be
|
78
87
|
# passed in as +id_value+.
|
79
|
-
def insert(
|
80
|
-
sql, binds = sql_for_insert(
|
88
|
+
def insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [])
|
89
|
+
sql, binds = sql_for_insert(to_sql(arel), pk, id_value, sequence_name, binds)
|
81
90
|
value = exec_insert(sql, name, binds)
|
82
91
|
id_value || last_inserted_id(value)
|
83
92
|
end
|
84
93
|
|
85
94
|
# Executes the update statement and returns the number of rows affected.
|
86
|
-
def update(
|
87
|
-
exec_update(
|
95
|
+
def update(arel, name = nil, binds = [])
|
96
|
+
exec_update(to_sql(arel), name, binds)
|
88
97
|
end
|
89
98
|
|
90
99
|
# Executes the delete statement and returns the number of rows affected.
|
91
|
-
def delete(
|
92
|
-
exec_delete(
|
100
|
+
def delete(arel, name = nil, binds = [])
|
101
|
+
exec_delete(to_sql(arel), name, binds)
|
93
102
|
end
|
94
103
|
|
95
104
|
# Checks whether there is currently no transaction active. This is done
|
@@ -324,6 +333,16 @@ module ActiveRecord
|
|
324
333
|
end
|
325
334
|
end
|
326
335
|
|
336
|
+
# The default strategy for an UPDATE with joins is to use a subquery. This doesn't work
|
337
|
+
# on mysql (even when aliasing the tables), but mysql allows using JOIN directly in
|
338
|
+
# an UPDATE statement, so in the mysql adapters we redefine this to do that.
|
339
|
+
def join_to_update(update, select) #:nodoc:
|
340
|
+
subselect = select.clone
|
341
|
+
subselect.projections = [update.key]
|
342
|
+
|
343
|
+
update.where update.key.in(subselect)
|
344
|
+
end
|
345
|
+
|
327
346
|
protected
|
328
347
|
# Returns an array of record hashes with the column names as keys and
|
329
348
|
# column values as values.
|
@@ -55,9 +55,10 @@ module ActiveRecord
|
|
55
55
|
@query_cache.clear
|
56
56
|
end
|
57
57
|
|
58
|
-
def select_all(
|
58
|
+
def select_all(arel, name = nil, binds = [])
|
59
59
|
if @query_cache_enabled
|
60
|
-
|
60
|
+
sql = to_sql(arel)
|
61
|
+
cache_sql(sql, binds) { super(sql, name, binds) }
|
61
62
|
else
|
62
63
|
super
|
63
64
|
end
|
@@ -2,6 +2,7 @@ require 'date'
|
|
2
2
|
require 'bigdecimal'
|
3
3
|
require 'bigdecimal/util'
|
4
4
|
require 'active_support/core_ext/benchmark'
|
5
|
+
require 'active_support/deprecation'
|
5
6
|
|
6
7
|
# TODO: Autoload these files
|
7
8
|
require 'active_record/connection_adapters/column'
|
@@ -38,12 +39,33 @@ module ActiveRecord
|
|
38
39
|
|
39
40
|
define_callbacks :checkout, :checkin
|
40
41
|
|
42
|
+
attr_accessor :visitor
|
43
|
+
|
41
44
|
def initialize(connection, logger = nil) #:nodoc:
|
42
45
|
@active = nil
|
43
46
|
@connection, @logger = connection, logger
|
44
47
|
@query_cache_enabled = false
|
45
48
|
@query_cache = Hash.new { |h,sql| h[sql] = {} }
|
46
49
|
@instrumenter = ActiveSupport::Notifications.instrumenter
|
50
|
+
@visitor = nil
|
51
|
+
end
|
52
|
+
|
53
|
+
# Returns a visitor instance for this adaptor, which conforms to the Arel::ToSql interface
|
54
|
+
def self.visitor_for(pool) # :nodoc:
|
55
|
+
adapter = pool.spec.config[:adapter]
|
56
|
+
|
57
|
+
if Arel::Visitors::VISITORS[adapter]
|
58
|
+
ActiveSupport::Deprecation.warn(
|
59
|
+
"Arel::Visitors::VISITORS is deprecated and will be removed. Database adapters " \
|
60
|
+
"should define a visitor_for method which returns the appropriate visitor for " \
|
61
|
+
"the database. For example, MysqlAdapter.visitor_for(pool) returns " \
|
62
|
+
"Arel::Visitors::MySQL.new(pool)."
|
63
|
+
)
|
64
|
+
|
65
|
+
Arel::Visitors::VISITORS[adapter].new(pool)
|
66
|
+
else
|
67
|
+
Arel::Visitors::ToSql.new(pool)
|
68
|
+
end
|
47
69
|
end
|
48
70
|
|
49
71
|
# Returns the human-readable name of the adapter. Use mixed case - one
|
@@ -129,6 +129,10 @@ module ActiveRecord
|
|
129
129
|
configure_connection
|
130
130
|
end
|
131
131
|
|
132
|
+
def self.visitor_for(pool) # :nodoc:
|
133
|
+
Arel::Visitors::MySQL.new(pool)
|
134
|
+
end
|
135
|
+
|
132
136
|
def adapter_name
|
133
137
|
ADAPTER_NAME
|
134
138
|
end
|
@@ -165,7 +169,7 @@ module ActiveRecord
|
|
165
169
|
end
|
166
170
|
|
167
171
|
def quote_column_name(name) #:nodoc:
|
168
|
-
@quoted_column_names[name] ||= "`#{name}`"
|
172
|
+
@quoted_column_names[name] ||= "`#{name.to_s.gsub('`', '``')}`"
|
169
173
|
end
|
170
174
|
|
171
175
|
def quote_table_name(name) #:nodoc:
|
@@ -595,6 +599,27 @@ module ActiveRecord
|
|
595
599
|
where_sql
|
596
600
|
end
|
597
601
|
|
602
|
+
# In the simple case, MySQL allows us to place JOINs directly into the UPDATE
|
603
|
+
# query. However, this does not allow for LIMIT, OFFSET and ORDER. To support
|
604
|
+
# these, we must use a subquery. However, MySQL is too stupid to create a
|
605
|
+
# temporary table for this automatically, so we have to give it some prompting
|
606
|
+
# in the form of a subsubquery. Ugh!
|
607
|
+
def join_to_update(update, select) #:nodoc:
|
608
|
+
if select.limit || select.offset || select.orders.any?
|
609
|
+
subsubselect = select.clone
|
610
|
+
subsubselect.projections = [update.key]
|
611
|
+
|
612
|
+
subselect = Arel::SelectManager.new(select.engine)
|
613
|
+
subselect.project Arel.sql(update.key.name)
|
614
|
+
subselect.from subsubselect.as('__active_record_temp')
|
615
|
+
|
616
|
+
update.where update.key.in(subselect)
|
617
|
+
else
|
618
|
+
update.table select.source
|
619
|
+
update.wheres = select.constraints
|
620
|
+
end
|
621
|
+
end
|
622
|
+
|
598
623
|
protected
|
599
624
|
def quoted_columns_for_index(column_names, options = {})
|
600
625
|
length = options[:length] if options.is_a?(Hash)
|
@@ -193,6 +193,10 @@ module ActiveRecord
|
|
193
193
|
connect
|
194
194
|
end
|
195
195
|
|
196
|
+
def self.visitor_for(pool) # :nodoc:
|
197
|
+
Arel::Visitors::MySQL.new(pool)
|
198
|
+
end
|
199
|
+
|
196
200
|
def adapter_name #:nodoc:
|
197
201
|
ADAPTER_NAME
|
198
202
|
end
|
@@ -247,7 +251,7 @@ module ActiveRecord
|
|
247
251
|
end
|
248
252
|
|
249
253
|
def quote_column_name(name) #:nodoc:
|
250
|
-
@quoted_column_names[name] ||= "`#{name}`"
|
254
|
+
@quoted_column_names[name] ||= "`#{name.to_s.gsub('`', '``')}`"
|
251
255
|
end
|
252
256
|
|
253
257
|
def quote_table_name(name) #:nodoc:
|
@@ -501,6 +505,27 @@ module ActiveRecord
|
|
501
505
|
end
|
502
506
|
deprecate :add_limit_offset!
|
503
507
|
|
508
|
+
# In the simple case, MySQL allows us to place JOINs directly into the UPDATE
|
509
|
+
# query. However, this does not allow for LIMIT, OFFSET and ORDER. To support
|
510
|
+
# these, we must use a subquery. However, MySQL is too stupid to create a
|
511
|
+
# temporary table for this automatically, so we have to give it some prompting
|
512
|
+
# in the form of a subsubquery. Ugh!
|
513
|
+
def join_to_update(update, select) #:nodoc:
|
514
|
+
if select.limit || select.offset || select.orders.any?
|
515
|
+
subsubselect = select.clone
|
516
|
+
subsubselect.projections = [update.key]
|
517
|
+
|
518
|
+
subselect = Arel::SelectManager.new(select.engine)
|
519
|
+
subselect.project Arel.sql(update.key.name)
|
520
|
+
subselect.from subsubselect.as('__active_record_temp')
|
521
|
+
|
522
|
+
update.where update.key.in(subselect)
|
523
|
+
else
|
524
|
+
update.table select.source
|
525
|
+
update.wheres = select.constraints
|
526
|
+
end
|
527
|
+
end
|
528
|
+
|
504
529
|
# SCHEMA STATEMENTS ========================================
|
505
530
|
|
506
531
|
def structure_dump #:nodoc:
|
@@ -266,6 +266,10 @@ module ActiveRecord
|
|
266
266
|
@local_tz = execute('SHOW TIME ZONE', 'SCHEMA').first["TimeZone"]
|
267
267
|
end
|
268
268
|
|
269
|
+
def self.visitor_for(pool) # :nodoc:
|
270
|
+
Arel::Visitors::PostgreSQL.new(pool)
|
271
|
+
end
|
272
|
+
|
269
273
|
# Clears the prepared statements cache.
|
270
274
|
def clear_cache!
|
271
275
|
@statements.each_value do |value|
|
@@ -54,6 +54,10 @@ module ActiveRecord
|
|
54
54
|
@config = config
|
55
55
|
end
|
56
56
|
|
57
|
+
def self.visitor_for(pool) # :nodoc:
|
58
|
+
Arel::Visitors::SQLite.new(pool)
|
59
|
+
end
|
60
|
+
|
57
61
|
def adapter_name #:nodoc:
|
58
62
|
'SQLite'
|
59
63
|
end
|
@@ -142,7 +146,7 @@ module ActiveRecord
|
|
142
146
|
end
|
143
147
|
|
144
148
|
def quote_column_name(name) #:nodoc:
|
145
|
-
%Q("#{name}")
|
149
|
+
%Q("#{name.to_s.gsub('"', '""')}")
|
146
150
|
end
|
147
151
|
|
148
152
|
# Quote date/time values for use in SQL input. Includes microseconds
|
@@ -33,7 +33,7 @@ module ActiveRecord
|
|
33
33
|
stmt = unscoped.where(arel_table[primary_key].eq(object.id)).arel.compile_update({
|
34
34
|
arel_table[counter_name] => object.send(association).count
|
35
35
|
})
|
36
|
-
connection.update stmt
|
36
|
+
connection.update stmt
|
37
37
|
end
|
38
38
|
return true
|
39
39
|
end
|
@@ -70,7 +70,7 @@ module ActiveRecord
|
|
70
70
|
|
71
71
|
# If the locking column has no default value set,
|
72
72
|
# start the lock version at zero. Note we can't use
|
73
|
-
# <tt>locking_enabled?</tt> at this point as
|
73
|
+
# <tt>locking_enabled?</tt> at this point as
|
74
74
|
# <tt>@attributes</tt> may not have been initialized yet.
|
75
75
|
|
76
76
|
if result.key?(self.class.locking_column) && lock_optimistically
|
@@ -100,7 +100,7 @@ module ActiveRecord
|
|
100
100
|
)
|
101
101
|
).arel.compile_update(arel_attributes_values(false, false, attribute_names))
|
102
102
|
|
103
|
-
affected_rows = connection.update stmt
|
103
|
+
affected_rows = connection.update stmt
|
104
104
|
|
105
105
|
unless affected_rows == 1
|
106
106
|
raise ActiveRecord::StaleObjectError, "Attempted to update a stale object: #{self.class.name}"
|
@@ -332,6 +332,10 @@ module ActiveRecord
|
|
332
332
|
(delegate || superclass.delegate).send(name, *args, &block)
|
333
333
|
end
|
334
334
|
|
335
|
+
def self.migrate(direction)
|
336
|
+
new.migrate direction
|
337
|
+
end
|
338
|
+
|
335
339
|
cattr_accessor :verbose
|
336
340
|
|
337
341
|
attr_accessor :name, :version
|
@@ -559,7 +563,7 @@ module ActiveRecord
|
|
559
563
|
|
560
564
|
def get_all_versions
|
561
565
|
table = Arel::Table.new(schema_migrations_table_name)
|
562
|
-
Base.connection.select_values(table.project(table['version'])
|
566
|
+
Base.connection.select_values(table.project(table['version'])).map{ |v| v.to_i }.sort
|
563
567
|
end
|
564
568
|
|
565
569
|
def current_version
|
@@ -716,11 +720,11 @@ module ActiveRecord
|
|
716
720
|
if down?
|
717
721
|
@migrated_versions.delete(version)
|
718
722
|
stmt = table.where(table["version"].eq(version.to_s)).compile_delete
|
719
|
-
Base.connection.delete stmt
|
723
|
+
Base.connection.delete stmt
|
720
724
|
else
|
721
725
|
@migrated_versions.push(version).sort!
|
722
726
|
stmt = table.compile_insert table["version"] => version.to_s
|
723
|
-
Base.connection.insert stmt
|
727
|
+
Base.connection.insert stmt
|
724
728
|
end
|
725
729
|
end
|
726
730
|
|
@@ -111,7 +111,7 @@ module ActiveRecord
|
|
111
111
|
callback_meth = :"_notify_#{observer_name}_for_#{callback}"
|
112
112
|
unless klass.respond_to?(callback_meth)
|
113
113
|
klass.send(:define_method, callback_meth) do |&block|
|
114
|
-
observer.
|
114
|
+
observer.update(callback, self, &block)
|
115
115
|
end
|
116
116
|
klass.send(callback, callback_meth)
|
117
117
|
end
|
@@ -302,7 +302,7 @@ module ActiveRecord
|
|
302
302
|
return 0 if attributes_with_values.empty?
|
303
303
|
klass = self.class
|
304
304
|
stmt = klass.unscoped.where(klass.arel_table[klass.primary_key].eq(id)).arel.compile_update(attributes_with_values)
|
305
|
-
klass.connection.update stmt
|
305
|
+
klass.connection.update stmt
|
306
306
|
end
|
307
307
|
|
308
308
|
# Creates a record with values matching those of the instance attributes
|
@@ -341,7 +341,8 @@ db_namespace = namespace :db do
|
|
341
341
|
desc 'Create a db/schema.rb file that can be portably used against any DB supported by AR'
|
342
342
|
task :dump => :load_config do
|
343
343
|
require 'active_record/schema_dumper'
|
344
|
-
|
344
|
+
filename = ENV['SCHEMA'] || "#{Rails.root}/db/schema.rb"
|
345
|
+
File.open(filename, "w:utf-8") do |file|
|
345
346
|
ActiveRecord::Base.establish_connection(Rails.env)
|
346
347
|
ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
|
347
348
|
end
|
@@ -68,7 +68,7 @@ module ActiveRecord
|
|
68
68
|
end
|
69
69
|
|
70
70
|
conn.insert(
|
71
|
-
im
|
71
|
+
im,
|
72
72
|
'SQL',
|
73
73
|
primary_key,
|
74
74
|
primary_key_value,
|
@@ -108,10 +108,10 @@ module ActiveRecord
|
|
108
108
|
|
109
109
|
if default_scoped.equal?(self)
|
110
110
|
@records = if @readonly_value.nil? && !@klass.locking_enabled?
|
111
|
-
eager_loading? ? find_with_associations : @klass.find_by_sql(arel
|
111
|
+
eager_loading? ? find_with_associations : @klass.find_by_sql(arel, @bind_values)
|
112
112
|
else
|
113
113
|
IdentityMap.without do
|
114
|
-
eager_loading? ? find_with_associations : @klass.find_by_sql(arel
|
114
|
+
eager_loading? ? find_with_associations : @klass.find_by_sql(arel, @bind_values)
|
115
115
|
end
|
116
116
|
end
|
117
117
|
|
@@ -216,15 +216,21 @@ module ActiveRecord
|
|
216
216
|
if conditions || options.present?
|
217
217
|
where(conditions).apply_finder_options(options.slice(:limit, :order)).update_all(updates)
|
218
218
|
else
|
219
|
-
stmt =
|
219
|
+
stmt = Arel::UpdateManager.new(arel.engine)
|
220
220
|
|
221
|
-
|
222
|
-
|
221
|
+
stmt.set Arel.sql(@klass.send(:sanitize_sql_for_assignment, updates))
|
222
|
+
stmt.table(table)
|
223
|
+
stmt.key = table[primary_key]
|
224
|
+
|
225
|
+
if joins_values.any?
|
226
|
+
@klass.connection.join_to_update(stmt, arel)
|
227
|
+
else
|
228
|
+
stmt.take(arel.limit)
|
229
|
+
stmt.order(*arel.orders)
|
230
|
+
stmt.wheres = arel.constraints
|
223
231
|
end
|
224
232
|
|
225
|
-
|
226
|
-
stmt.key = table[primary_key]
|
227
|
-
@klass.connection.update stmt.to_sql, 'SQL', bind_values
|
233
|
+
@klass.connection.update stmt, 'SQL', bind_values
|
228
234
|
end
|
229
235
|
end
|
230
236
|
|
@@ -342,8 +348,7 @@ module ActiveRecord
|
|
342
348
|
where(conditions).delete_all
|
343
349
|
else
|
344
350
|
statement = arel.compile_delete
|
345
|
-
affected = @klass.connection.delete(
|
346
|
-
statement.to_sql, 'SQL', bind_values)
|
351
|
+
affected = @klass.connection.delete(statement, 'SQL', bind_values)
|
347
352
|
|
348
353
|
reset
|
349
354
|
affected
|
@@ -389,7 +394,7 @@ module ActiveRecord
|
|
389
394
|
end
|
390
395
|
|
391
396
|
def to_sql
|
392
|
-
@to_sql ||=
|
397
|
+
@to_sql ||= klass.connection.to_sql(arel)
|
393
398
|
end
|
394
399
|
|
395
400
|
def where_values_hash
|
@@ -219,7 +219,7 @@ module ActiveRecord
|
|
219
219
|
query_builder = relation.arel
|
220
220
|
end
|
221
221
|
|
222
|
-
type_cast_calculated_value(@klass.connection.select_value(query_builder
|
222
|
+
type_cast_calculated_value(@klass.connection.select_value(query_builder), column_for(column_name), operation)
|
223
223
|
end
|
224
224
|
|
225
225
|
def execute_grouped_calculation(operation, column_name, distinct) #:nodoc:
|
@@ -254,7 +254,7 @@ module ActiveRecord
|
|
254
254
|
relation = except(:group).group(group.join(','))
|
255
255
|
relation.select_values = select_values
|
256
256
|
|
257
|
-
calculated_data = @klass.connection.select_all(relation
|
257
|
+
calculated_data = @klass.connection.select_all(relation)
|
258
258
|
|
259
259
|
if association
|
260
260
|
key_ids = calculated_data.collect { |row| row[group_aliases.first] }
|
@@ -194,7 +194,7 @@ module ActiveRecord
|
|
194
194
|
relation = relation.where(table[primary_key].eq(id)) if id
|
195
195
|
end
|
196
196
|
|
197
|
-
connection.select_value(relation
|
197
|
+
connection.select_value(relation) ? true : false
|
198
198
|
end
|
199
199
|
|
200
200
|
protected
|
@@ -202,7 +202,7 @@ module ActiveRecord
|
|
202
202
|
def find_with_associations
|
203
203
|
join_dependency = construct_join_dependency_for_association_find
|
204
204
|
relation = construct_relation_for_association_find(join_dependency)
|
205
|
-
rows = connection.select_all(relation
|
205
|
+
rows = connection.select_all(relation, 'SQL', relation.bind_values)
|
206
206
|
join_dependency.instantiate(rows)
|
207
207
|
rescue ThrowResult
|
208
208
|
[]
|
@@ -40,6 +40,10 @@ module ActiveRecord
|
|
40
40
|
def header(stream)
|
41
41
|
define_params = @version ? ":version => #{@version}" : ""
|
42
42
|
|
43
|
+
if stream.respond_to?(:external_encoding)
|
44
|
+
stream.puts "# encoding: #{stream.external_encoding.name}"
|
45
|
+
end
|
46
|
+
|
43
47
|
stream.puts <<HEADER
|
44
48
|
# This file is auto-generated from the current state of the database. Instead
|
45
49
|
# of editing this file, please use the migrations feature of Active Record to
|
@@ -17,15 +17,7 @@ module ActiveRecord
|
|
17
17
|
# validates_associated :pages, :library
|
18
18
|
# end
|
19
19
|
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
# class Page < ActiveRecord::Base
|
23
|
-
# belongs_to :book
|
24
|
-
#
|
25
|
-
# validates_associated :book
|
26
|
-
# end
|
27
|
-
#
|
28
|
-
# this would specify a circular dependency and cause infinite recursion.
|
20
|
+
# WARNING: This validation must not be used on both ends of an association. Doing so will lead to a circular dependency and cause infinite recursion.
|
29
21
|
#
|
30
22
|
# NOTE: This validation will not fail if the association hasn't been assigned. If you want to
|
31
23
|
# ensure that the association is both present and guaranteed to be valid, you also need to
|
metadata
CHANGED
@@ -1,13 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 15424105
|
5
|
+
prerelease: 6
|
5
6
|
segments:
|
6
7
|
- 3
|
7
8
|
- 1
|
8
9
|
- 0
|
9
|
-
-
|
10
|
-
|
10
|
+
- rc
|
11
|
+
- 6
|
12
|
+
version: 3.1.0.rc6
|
11
13
|
platform: ruby
|
12
14
|
authors:
|
13
15
|
- David Heinemeier Hansson
|
@@ -15,60 +17,69 @@ autorequire:
|
|
15
17
|
bindir: bin
|
16
18
|
cert_chain: []
|
17
19
|
|
18
|
-
date: 2011-
|
19
|
-
default_executable:
|
20
|
+
date: 2011-08-16 00:00:00 Z
|
20
21
|
dependencies:
|
21
22
|
- !ruby/object:Gem::Dependency
|
22
23
|
name: activesupport
|
23
24
|
prerelease: false
|
24
25
|
requirement: &id001 !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
25
27
|
requirements:
|
26
28
|
- - "="
|
27
29
|
- !ruby/object:Gem::Version
|
30
|
+
hash: 15424105
|
28
31
|
segments:
|
29
32
|
- 3
|
30
33
|
- 1
|
31
34
|
- 0
|
32
|
-
-
|
33
|
-
|
35
|
+
- rc
|
36
|
+
- 6
|
37
|
+
version: 3.1.0.rc6
|
34
38
|
type: :runtime
|
35
39
|
version_requirements: *id001
|
36
40
|
- !ruby/object:Gem::Dependency
|
37
41
|
name: activemodel
|
38
42
|
prerelease: false
|
39
43
|
requirement: &id002 !ruby/object:Gem::Requirement
|
44
|
+
none: false
|
40
45
|
requirements:
|
41
46
|
- - "="
|
42
47
|
- !ruby/object:Gem::Version
|
48
|
+
hash: 15424105
|
43
49
|
segments:
|
44
50
|
- 3
|
45
51
|
- 1
|
46
52
|
- 0
|
47
|
-
-
|
48
|
-
|
53
|
+
- rc
|
54
|
+
- 6
|
55
|
+
version: 3.1.0.rc6
|
49
56
|
type: :runtime
|
50
57
|
version_requirements: *id002
|
51
58
|
- !ruby/object:Gem::Dependency
|
52
59
|
name: arel
|
53
60
|
prerelease: false
|
54
61
|
requirement: &id003 !ruby/object:Gem::Requirement
|
62
|
+
none: false
|
55
63
|
requirements:
|
56
64
|
- - ~>
|
57
65
|
- !ruby/object:Gem::Version
|
66
|
+
hash: 5
|
58
67
|
segments:
|
59
68
|
- 2
|
69
|
+
- 2
|
60
70
|
- 1
|
61
|
-
|
62
|
-
version: 2.1.4
|
71
|
+
version: 2.2.1
|
63
72
|
type: :runtime
|
64
73
|
version_requirements: *id003
|
65
74
|
- !ruby/object:Gem::Dependency
|
66
75
|
name: tzinfo
|
67
76
|
prerelease: false
|
68
77
|
requirement: &id004 !ruby/object:Gem::Requirement
|
78
|
+
none: false
|
69
79
|
requirements:
|
70
80
|
- - ~>
|
71
81
|
- !ruby/object:Gem::Version
|
82
|
+
hash: 41
|
72
83
|
segments:
|
73
84
|
- 0
|
74
85
|
- 3
|
@@ -212,7 +223,6 @@ files:
|
|
212
223
|
- lib/rails/generators/active_record/session_migration/session_migration_generator.rb
|
213
224
|
- lib/rails/generators/active_record/session_migration/templates/migration.rb
|
214
225
|
- lib/rails/generators/active_record.rb
|
215
|
-
has_rdoc: true
|
216
226
|
homepage: http://www.rubyonrails.org
|
217
227
|
licenses: []
|
218
228
|
|
@@ -223,18 +233,22 @@ rdoc_options:
|
|
223
233
|
require_paths:
|
224
234
|
- lib
|
225
235
|
required_ruby_version: !ruby/object:Gem::Requirement
|
236
|
+
none: false
|
226
237
|
requirements:
|
227
238
|
- - ">="
|
228
239
|
- !ruby/object:Gem::Version
|
240
|
+
hash: 57
|
229
241
|
segments:
|
230
242
|
- 1
|
231
243
|
- 8
|
232
244
|
- 7
|
233
245
|
version: 1.8.7
|
234
246
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
247
|
+
none: false
|
235
248
|
requirements:
|
236
249
|
- - ">"
|
237
250
|
- !ruby/object:Gem::Version
|
251
|
+
hash: 25
|
238
252
|
segments:
|
239
253
|
- 1
|
240
254
|
- 3
|
@@ -243,7 +257,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
243
257
|
requirements: []
|
244
258
|
|
245
259
|
rubyforge_project:
|
246
|
-
rubygems_version: 1.
|
260
|
+
rubygems_version: 1.8.8
|
247
261
|
signing_key:
|
248
262
|
specification_version: 3
|
249
263
|
summary: Object-relational mapper framework (part of Rails).
|