activerecord 5.2.0.beta2 → 5.2.0.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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +231 -2
- data/MIT-LICENSE +1 -1
- data/README.rdoc +1 -1
- data/lib/active_record.rb +1 -1
- data/lib/active_record/aggregations.rb +4 -5
- data/lib/active_record/association_relation.rb +2 -2
- data/lib/active_record/associations.rb +18 -12
- data/lib/active_record/associations/alias_tracker.rb +2 -10
- data/lib/active_record/associations/association.rb +1 -1
- data/lib/active_record/associations/belongs_to_association.rb +9 -9
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +1 -6
- data/lib/active_record/associations/builder/association.rb +2 -2
- data/lib/active_record/associations/builder/belongs_to.rb +7 -3
- data/lib/active_record/associations/collection_association.rb +2 -2
- data/lib/active_record/associations/collection_proxy.rb +1 -1
- data/lib/active_record/associations/has_many_association.rb +1 -1
- data/lib/active_record/associations/has_many_through_association.rb +4 -17
- data/lib/active_record/associations/has_one_through_association.rb +5 -6
- data/lib/active_record/associations/preloader.rb +1 -1
- data/lib/active_record/associations/preloader/association.rb +2 -2
- data/lib/active_record/associations/through_association.rb +22 -9
- data/lib/active_record/attribute_methods.rb +1 -5
- data/lib/active_record/attribute_methods/dirty.rb +2 -4
- data/lib/active_record/attributes.rb +1 -1
- data/lib/active_record/autosave_association.rb +3 -0
- data/lib/active_record/callbacks.rb +2 -2
- data/lib/active_record/collection_cache_key.rb +5 -6
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +1 -3
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +57 -21
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +1 -0
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +20 -3
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +55 -15
- data/lib/active_record/connection_adapters/abstract_adapter.rb +19 -6
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +55 -64
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +8 -1
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +0 -4
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +21 -6
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +9 -1
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +12 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +13 -4
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +170 -48
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +15 -5
- data/lib/active_record/connection_adapters/schema_cache.rb +2 -2
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +63 -18
- data/lib/active_record/core.rb +12 -3
- data/lib/active_record/enum.rb +2 -0
- data/lib/active_record/fixtures.rb +28 -37
- data/lib/active_record/gem_version.rb +1 -1
- data/lib/active_record/inheritance.rb +3 -4
- data/lib/active_record/log_subscriber.rb +41 -0
- data/lib/active_record/migration.rb +138 -120
- data/lib/active_record/migration/compatibility.rb +20 -0
- data/lib/active_record/model_schema.rb +19 -16
- data/lib/active_record/persistence.rb +8 -11
- data/lib/active_record/railtie.rb +7 -2
- data/lib/active_record/railties/databases.rake +8 -11
- data/lib/active_record/reflection.rb +10 -13
- data/lib/active_record/relation.rb +27 -17
- data/lib/active_record/relation/calculations.rb +17 -12
- data/lib/active_record/relation/finder_methods.rb +30 -37
- data/lib/active_record/relation/merger.rb +30 -2
- data/lib/active_record/relation/predicate_builder.rb +12 -0
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +1 -1
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +1 -1
- data/lib/active_record/relation/query_methods.rb +14 -24
- data/lib/active_record/relation/spawn_methods.rb +1 -1
- data/lib/active_record/relation/where_clause.rb +16 -2
- data/lib/active_record/relation/where_clause_factory.rb +1 -2
- data/lib/active_record/sanitization.rb +130 -128
- data/lib/active_record/schema.rb +1 -1
- data/lib/active_record/schema_dumper.rb +12 -3
- data/lib/active_record/scoping/named.rb +6 -0
- data/lib/active_record/store.rb +1 -1
- data/lib/active_record/table_metadata.rb +10 -3
- data/lib/active_record/tasks/database_tasks.rb +4 -4
- data/lib/active_record/type_caster/map.rb +1 -1
- metadata +9 -9
@@ -12,17 +12,20 @@ module ActiveRecord
|
|
12
12
|
if record
|
13
13
|
raise_on_type_mismatch!(record)
|
14
14
|
update_counters_on_replace(record)
|
15
|
-
replace_keys(record)
|
16
15
|
set_inverse_instance(record)
|
17
16
|
@updated = true
|
18
17
|
else
|
19
18
|
decrement_counters
|
20
|
-
remove_keys
|
21
19
|
end
|
22
20
|
|
23
21
|
self.target = record
|
24
22
|
end
|
25
23
|
|
24
|
+
def target=(record)
|
25
|
+
replace_keys(record)
|
26
|
+
super
|
27
|
+
end
|
28
|
+
|
26
29
|
def default(&block)
|
27
30
|
writer(owner.instance_exec(&block)) if reader.nil?
|
28
31
|
end
|
@@ -49,9 +52,9 @@ module ActiveRecord
|
|
49
52
|
def update_counters(by)
|
50
53
|
if require_counter_update? && foreign_key_present?
|
51
54
|
if target && !stale_target?
|
52
|
-
target.increment!(reflection.counter_cache_column, by)
|
55
|
+
target.increment!(reflection.counter_cache_column, by, touch: reflection.options[:touch])
|
53
56
|
else
|
54
|
-
klass.update_counters(target_id, reflection.counter_cache_column => by)
|
57
|
+
klass.update_counters(target_id, reflection.counter_cache_column => by, touch: reflection.options[:touch])
|
55
58
|
end
|
56
59
|
end
|
57
60
|
end
|
@@ -78,11 +81,8 @@ module ActiveRecord
|
|
78
81
|
end
|
79
82
|
|
80
83
|
def replace_keys(record)
|
81
|
-
owner[reflection.foreign_key] = record
|
82
|
-
|
83
|
-
|
84
|
-
def remove_keys
|
85
|
-
owner[reflection.foreign_key] = nil
|
84
|
+
owner[reflection.foreign_key] = record ?
|
85
|
+
record._read_attribute(reflection.association_primary_key(record.class)) : nil
|
86
86
|
end
|
87
87
|
|
88
88
|
def foreign_key_present?
|
@@ -13,12 +13,7 @@ module ActiveRecord
|
|
13
13
|
|
14
14
|
def replace_keys(record)
|
15
15
|
super
|
16
|
-
owner[reflection.foreign_type] = record.class.base_class.name
|
17
|
-
end
|
18
|
-
|
19
|
-
def remove_keys
|
20
|
-
super
|
21
|
-
owner[reflection.foreign_type] = nil
|
16
|
+
owner[reflection.foreign_type] = record ? record.class.base_class.name : nil
|
22
17
|
end
|
23
18
|
|
24
19
|
def different_target?(record)
|
@@ -104,8 +104,8 @@ module ActiveRecord::Associations::Builder # :nodoc:
|
|
104
104
|
|
105
105
|
def self.define_readers(mixin, name)
|
106
106
|
mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1
|
107
|
-
def #{name}
|
108
|
-
association(:#{name}).reader
|
107
|
+
def #{name}
|
108
|
+
association(:#{name}).reader
|
109
109
|
end
|
110
110
|
CODE
|
111
111
|
end
|
@@ -114,9 +114,13 @@ module ActiveRecord::Associations::Builder # :nodoc:
|
|
114
114
|
BelongsTo.touch_record(record, record.send(changes_method), foreign_key, n, touch, belongs_to_touch_method)
|
115
115
|
}}
|
116
116
|
|
117
|
-
|
118
|
-
|
119
|
-
|
117
|
+
unless reflection.counter_cache_column
|
118
|
+
model.after_create callback.(:saved_changes), if: :saved_changes?
|
119
|
+
model.after_destroy callback.(:changes_to_save)
|
120
|
+
end
|
121
|
+
|
122
|
+
model.after_update callback.(:saved_changes), if: :saved_changes?
|
123
|
+
model.after_touch callback.(:changes_to_save)
|
120
124
|
end
|
121
125
|
|
122
126
|
def self.add_default_callbacks(model, reflection)
|
@@ -52,11 +52,11 @@ module ActiveRecord
|
|
52
52
|
|
53
53
|
# Implements the ids writer method, e.g. foo.item_ids= for Foo.has_many :items
|
54
54
|
def ids_writer(ids)
|
55
|
-
|
55
|
+
primary_key = reflection.association_primary_key
|
56
|
+
pk_type = klass.type_for_attribute(primary_key)
|
56
57
|
ids = Array(ids).reject(&:blank?)
|
57
58
|
ids.map! { |i| pk_type.cast(i) }
|
58
59
|
|
59
|
-
primary_key = reflection.association_primary_key
|
60
60
|
records = klass.where(primary_key => ids).index_by do |r|
|
61
61
|
r.public_send(primary_key)
|
62
62
|
end.values_at(*ids).compact
|
@@ -32,7 +32,7 @@ module ActiveRecord
|
|
32
32
|
class CollectionProxy < Relation
|
33
33
|
def initialize(klass, association) #:nodoc:
|
34
34
|
@association = association
|
35
|
-
super klass
|
35
|
+
super klass
|
36
36
|
|
37
37
|
extensions = association.extensions
|
38
38
|
extend(*extensions) if extensions.any?
|
@@ -8,9 +8,7 @@ module ActiveRecord
|
|
8
8
|
|
9
9
|
def initialize(owner, reflection)
|
10
10
|
super
|
11
|
-
|
12
|
-
@through_records = {}
|
13
|
-
@through_association = nil
|
11
|
+
@through_records = {}
|
14
12
|
end
|
15
13
|
|
16
14
|
def concat(*records)
|
@@ -50,11 +48,6 @@ module ActiveRecord
|
|
50
48
|
end
|
51
49
|
|
52
50
|
private
|
53
|
-
|
54
|
-
def through_association
|
55
|
-
@through_association ||= owner.association(through_reflection.name)
|
56
|
-
end
|
57
|
-
|
58
51
|
# The through record (built with build_record) is temporarily cached
|
59
52
|
# so that it may be reused if insert_record is subsequently called.
|
60
53
|
#
|
@@ -140,21 +133,15 @@ module ActiveRecord
|
|
140
133
|
|
141
134
|
scope = through_association.scope
|
142
135
|
scope.where! construct_join_attributes(*records)
|
136
|
+
scope = scope.where(through_scope_attributes)
|
143
137
|
|
144
138
|
case method
|
145
139
|
when :destroy
|
146
140
|
if scope.klass.primary_key
|
147
|
-
count = scope.destroy_all.
|
141
|
+
count = scope.destroy_all.count(&:destroyed?)
|
148
142
|
else
|
149
143
|
scope.each(&:_run_destroy_callbacks)
|
150
|
-
|
151
|
-
arel = scope.arel
|
152
|
-
|
153
|
-
stmt = Arel::DeleteManager.new
|
154
|
-
stmt.from scope.klass.arel_table
|
155
|
-
stmt.wheres = arel.constraints
|
156
|
-
|
157
|
-
count = scope.klass.connection.delete(stmt, "SQL")
|
144
|
+
count = scope.delete_all
|
158
145
|
end
|
159
146
|
when :nullify
|
160
147
|
count = scope.update_all(source_reflection.foreign_key => nil)
|
@@ -6,17 +6,16 @@ module ActiveRecord
|
|
6
6
|
class HasOneThroughAssociation < HasOneAssociation #:nodoc:
|
7
7
|
include ThroughAssociation
|
8
8
|
|
9
|
-
def replace(record)
|
10
|
-
create_through_record(record)
|
9
|
+
def replace(record, save = true)
|
10
|
+
create_through_record(record, save)
|
11
11
|
self.target = record
|
12
12
|
end
|
13
13
|
|
14
14
|
private
|
15
|
-
|
16
|
-
def create_through_record(record)
|
15
|
+
def create_through_record(record, save)
|
17
16
|
ensure_not_nested
|
18
17
|
|
19
|
-
through_proxy =
|
18
|
+
through_proxy = through_association
|
20
19
|
through_record = through_proxy.load_target
|
21
20
|
|
22
21
|
if through_record && !record
|
@@ -30,7 +29,7 @@ module ActiveRecord
|
|
30
29
|
|
31
30
|
if through_record
|
32
31
|
through_record.update(attributes)
|
33
|
-
elsif owner.new_record?
|
32
|
+
elsif owner.new_record? || !save
|
34
33
|
through_proxy.build(attributes)
|
35
34
|
else
|
36
35
|
through_proxy.create(attributes)
|
@@ -82,11 +82,11 @@ module ActiveRecord
|
|
82
82
|
end
|
83
83
|
|
84
84
|
def association_key_type
|
85
|
-
@klass.type_for_attribute(association_key_name
|
85
|
+
@klass.type_for_attribute(association_key_name).type
|
86
86
|
end
|
87
87
|
|
88
88
|
def owner_key_type
|
89
|
-
@model.type_for_attribute(owner_key_name
|
89
|
+
@model.type_for_attribute(owner_key_name).type
|
90
90
|
end
|
91
91
|
|
92
92
|
def load_records(&block)
|
@@ -4,9 +4,24 @@ module ActiveRecord
|
|
4
4
|
module Associations
|
5
5
|
# = Active Record Through Association
|
6
6
|
module ThroughAssociation #:nodoc:
|
7
|
-
delegate :source_reflection,
|
7
|
+
delegate :source_reflection, to: :reflection
|
8
8
|
|
9
9
|
private
|
10
|
+
def through_reflection
|
11
|
+
@through_reflection ||= begin
|
12
|
+
refl = reflection.through_reflection
|
13
|
+
|
14
|
+
while refl.through_reflection?
|
15
|
+
refl = refl.through_reflection
|
16
|
+
end
|
17
|
+
|
18
|
+
refl
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def through_association
|
23
|
+
@through_association ||= owner.association(through_reflection.name)
|
24
|
+
end
|
10
25
|
|
11
26
|
# We merge in these scopes for two reasons:
|
12
27
|
#
|
@@ -38,24 +53,22 @@ module ActiveRecord
|
|
38
53
|
def construct_join_attributes(*records)
|
39
54
|
ensure_mutable
|
40
55
|
|
41
|
-
|
56
|
+
association_primary_key = source_reflection.association_primary_key(reflection.klass)
|
57
|
+
|
58
|
+
if association_primary_key == reflection.klass.primary_key && !options[:source_type]
|
42
59
|
join_attributes = { source_reflection.name => records }
|
43
60
|
else
|
44
61
|
join_attributes = {
|
45
|
-
source_reflection.foreign_key =>
|
46
|
-
records.map { |record|
|
47
|
-
record.send(source_reflection.association_primary_key(reflection.klass))
|
48
|
-
}
|
62
|
+
source_reflection.foreign_key => records.map(&association_primary_key.to_sym)
|
49
63
|
}
|
50
64
|
end
|
51
65
|
|
52
66
|
if options[:source_type]
|
53
|
-
join_attributes[source_reflection.foreign_type] =
|
54
|
-
records.map { |record| record.class.base_class.name }
|
67
|
+
join_attributes[source_reflection.foreign_type] = [ options[:source_type] ]
|
55
68
|
end
|
56
69
|
|
57
70
|
if records.count == 1
|
58
|
-
|
71
|
+
join_attributes.transform_values!(&:first)
|
59
72
|
else
|
60
73
|
join_attributes
|
61
74
|
end
|
@@ -456,7 +456,7 @@ module ActiveRecord
|
|
456
456
|
arel_table = self.class.arel_table
|
457
457
|
|
458
458
|
attribute_names.each do |name|
|
459
|
-
attrs[arel_table[name]] =
|
459
|
+
attrs[arel_table[name]] = _read_attribute(name)
|
460
460
|
end
|
461
461
|
attrs
|
462
462
|
end
|
@@ -483,9 +483,5 @@ module ActiveRecord
|
|
483
483
|
def pk_attribute?(name)
|
484
484
|
name == self.class.primary_key
|
485
485
|
end
|
486
|
-
|
487
|
-
def typecasted_attribute_value(name)
|
488
|
-
_read_attribute(name)
|
489
|
-
end
|
490
486
|
end
|
491
487
|
end
|
@@ -32,9 +32,7 @@ module ActiveRecord
|
|
32
32
|
# <tt>reload</tt> the record and clears changed attributes.
|
33
33
|
def reload(*)
|
34
34
|
super.tap do
|
35
|
-
@previously_changed = ActiveSupport::HashWithIndifferentAccess.new
|
36
35
|
@mutations_before_last_save = nil
|
37
|
-
@attributes_changed_by_setter = ActiveSupport::HashWithIndifferentAccess.new
|
38
36
|
@mutations_from_database = nil
|
39
37
|
end
|
40
38
|
end
|
@@ -114,12 +112,12 @@ module ActiveRecord
|
|
114
112
|
|
115
113
|
# Alias for +changed+
|
116
114
|
def changed_attribute_names_to_save
|
117
|
-
|
115
|
+
mutations_from_database.changed_attribute_names
|
118
116
|
end
|
119
117
|
|
120
118
|
# Alias for +changed_attributes+
|
121
119
|
def attributes_in_database
|
122
|
-
|
120
|
+
mutations_from_database.changed_values
|
123
121
|
end
|
124
122
|
|
125
123
|
private
|
@@ -57,7 +57,7 @@ module ActiveRecord
|
|
57
57
|
# store_listing = StoreListing.new(price_in_cents: '10.1')
|
58
58
|
#
|
59
59
|
# # before
|
60
|
-
# store_listing.price_in_cents # => BigDecimal
|
60
|
+
# store_listing.price_in_cents # => BigDecimal(10.1)
|
61
61
|
#
|
62
62
|
# class StoreListing < ActiveRecord::Base
|
63
63
|
# attribute :price_in_cents, :integer
|
@@ -436,6 +436,9 @@ module ActiveRecord
|
|
436
436
|
if (autosave && record.changed_for_autosave?) || new_record? || record_changed?(reflection, record, key)
|
437
437
|
unless reflection.through_reflection
|
438
438
|
record[reflection.foreign_key] = key
|
439
|
+
if inverse_reflection = reflection.inverse_of
|
440
|
+
record.association(inverse_reflection.name).loaded!
|
441
|
+
end
|
439
442
|
end
|
440
443
|
|
441
444
|
saved = record.save(validate: !autosave)
|
@@ -232,7 +232,7 @@ module ActiveRecord
|
|
232
232
|
#
|
233
233
|
# For example:
|
234
234
|
#
|
235
|
-
# class Topic
|
235
|
+
# class Topic < ActiveRecord::Base
|
236
236
|
# has_many :children
|
237
237
|
#
|
238
238
|
# after_save :log_children
|
@@ -257,7 +257,7 @@ module ActiveRecord
|
|
257
257
|
#
|
258
258
|
# For example:
|
259
259
|
#
|
260
|
-
# class Topic
|
260
|
+
# class Topic < ActiveRecord::Base
|
261
261
|
# has_many :children
|
262
262
|
#
|
263
263
|
# after_commit :log_children
|
@@ -3,11 +3,11 @@
|
|
3
3
|
module ActiveRecord
|
4
4
|
module CollectionCacheKey
|
5
5
|
def collection_cache_key(collection = all, timestamp_column = :updated_at) # :nodoc:
|
6
|
-
query_signature = Digest
|
6
|
+
query_signature = ActiveSupport::Digest.hexdigest(collection.to_sql)
|
7
7
|
key = "#{collection.model_name.cache_key}/query-#{query_signature}"
|
8
8
|
|
9
|
-
if collection.loaded?
|
10
|
-
size = collection.size
|
9
|
+
if collection.loaded? || collection.distinct_value
|
10
|
+
size = collection.records.size
|
11
11
|
if size > 0
|
12
12
|
timestamp = collection.max_by(×tamp_column)._read_attribute(timestamp_column)
|
13
13
|
end
|
@@ -15,13 +15,12 @@ module ActiveRecord
|
|
15
15
|
if collection.eager_loading?
|
16
16
|
collection = collection.send(:apply_join_dependency)
|
17
17
|
end
|
18
|
-
column_type = type_for_attribute(timestamp_column
|
18
|
+
column_type = type_for_attribute(timestamp_column)
|
19
19
|
column = connection.column_name_from_arel_node(collection.arel_attribute(timestamp_column))
|
20
20
|
select_values = "COUNT(*) AS #{connection.quote_column_name("size")}, MAX(%s) AS timestamp"
|
21
21
|
|
22
22
|
if collection.has_limit_or_offset?
|
23
|
-
query = collection.
|
24
|
-
query.select_values = [column]
|
23
|
+
query = collection.select(column)
|
25
24
|
subquery_alias = "subquery_for_cache_key"
|
26
25
|
subquery_column = "#{subquery_alias}.#{timestamp_column}"
|
27
26
|
subquery = query.arel.as(subquery_alias)
|
@@ -1005,9 +1005,7 @@ module ActiveRecord
|
|
1005
1005
|
def retrieve_connection(spec_name) #:nodoc:
|
1006
1006
|
pool = retrieve_connection_pool(spec_name)
|
1007
1007
|
raise ConnectionNotEstablished, "No connection pool with '#{spec_name}' found." unless pool
|
1008
|
-
|
1009
|
-
raise ConnectionNotEstablished, "No connection for '#{spec_name}' in connection pool" unless conn
|
1010
|
-
conn
|
1008
|
+
pool.connection
|
1011
1009
|
end
|
1012
1010
|
|
1013
1011
|
# Returns true if a connection that's accessible to this class has
|
@@ -356,35 +356,33 @@ module ActiveRecord
|
|
356
356
|
# Inserts a set of fixtures into the table. Overridden in adapters that require
|
357
357
|
# something beyond a simple insert (eg. Oracle).
|
358
358
|
def insert_fixtures(fixtures, table_name)
|
359
|
+
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
360
|
+
`insert_fixtures` is deprecated and will be removed in the next version of Rails.
|
361
|
+
Consider using `insert_fixtures_set` for performance improvement.
|
362
|
+
MSG
|
359
363
|
return if fixtures.empty?
|
360
364
|
|
361
|
-
|
365
|
+
execute(build_fixture_sql(fixtures, table_name), "Fixtures Insert")
|
366
|
+
end
|
362
367
|
|
363
|
-
|
364
|
-
|
368
|
+
def insert_fixtures_set(fixture_set, tables_to_delete = [])
|
369
|
+
fixture_inserts = fixture_set.map do |table_name, fixtures|
|
370
|
+
next if fixtures.empty?
|
365
371
|
|
366
|
-
|
367
|
-
|
368
|
-
raise Fixture::FixtureError, %(table "#{table_name}" has no columns named #{unknown_columns.map(&:inspect).join(', ')}.)
|
369
|
-
end
|
372
|
+
build_fixture_sql(fixtures, table_name)
|
373
|
+
end.compact
|
370
374
|
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
375
|
+
table_deletes = tables_to_delete.map { |table| "DELETE FROM #{quote_table_name table}".dup }
|
376
|
+
total_sql = Array.wrap(combine_multi_statements(table_deletes + fixture_inserts))
|
377
|
+
|
378
|
+
disable_referential_integrity do
|
379
|
+
transaction(requires_new: true) do
|
380
|
+
total_sql.each do |sql|
|
381
|
+
execute sql, "Fixtures Load"
|
382
|
+
yield if block_given?
|
378
383
|
end
|
379
384
|
end
|
380
385
|
end
|
381
|
-
|
382
|
-
table = Arel::Table.new(table_name)
|
383
|
-
manager = Arel::InsertManager.new
|
384
|
-
manager.into(table)
|
385
|
-
columns.each_key { |column| manager.columns << table[column] }
|
386
|
-
manager.values = manager.create_values_list(values)
|
387
|
-
execute manager.to_sql, "Fixtures Insert"
|
388
386
|
end
|
389
387
|
|
390
388
|
def empty_insert_statement_value
|
@@ -416,6 +414,44 @@ module ActiveRecord
|
|
416
414
|
alias join_to_delete join_to_update
|
417
415
|
|
418
416
|
private
|
417
|
+
def default_insert_value(column)
|
418
|
+
Arel.sql("DEFAULT")
|
419
|
+
end
|
420
|
+
|
421
|
+
def build_fixture_sql(fixtures, table_name)
|
422
|
+
columns = schema_cache.columns_hash(table_name)
|
423
|
+
|
424
|
+
values = fixtures.map do |fixture|
|
425
|
+
fixture = fixture.stringify_keys
|
426
|
+
|
427
|
+
unknown_columns = fixture.keys - columns.keys
|
428
|
+
if unknown_columns.any?
|
429
|
+
raise Fixture::FixtureError, %(table "#{table_name}" has no columns named #{unknown_columns.map(&:inspect).join(', ')}.)
|
430
|
+
end
|
431
|
+
|
432
|
+
columns.map do |name, column|
|
433
|
+
if fixture.key?(name)
|
434
|
+
type = lookup_cast_type_from_column(column)
|
435
|
+
bind = Relation::QueryAttribute.new(name, fixture[name], type)
|
436
|
+
with_yaml_fallback(bind.value_for_database)
|
437
|
+
else
|
438
|
+
default_insert_value(column)
|
439
|
+
end
|
440
|
+
end
|
441
|
+
end
|
442
|
+
|
443
|
+
table = Arel::Table.new(table_name)
|
444
|
+
manager = Arel::InsertManager.new
|
445
|
+
manager.into(table)
|
446
|
+
columns.each_key { |column| manager.columns << table[column] }
|
447
|
+
manager.values = manager.create_values_list(values)
|
448
|
+
|
449
|
+
manager.to_sql
|
450
|
+
end
|
451
|
+
|
452
|
+
def combine_multi_statements(total_sql)
|
453
|
+
total_sql.join(";\n")
|
454
|
+
end
|
419
455
|
|
420
456
|
# Returns a subquery for the given key using the join information.
|
421
457
|
def subquery_for(key, select)
|