activerecord 4.1.1 → 4.1.2.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 +7 -0
- data/CHANGELOG.md +312 -0
- data/lib/active_record/association_relation.rb +4 -0
- data/lib/active_record/associations.rb +24 -3
- data/lib/active_record/associations/association.rb +1 -1
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +10 -4
- data/lib/active_record/associations/builder/has_many.rb +1 -1
- data/lib/active_record/associations/collection_association.rb +5 -5
- data/lib/active_record/associations/collection_proxy.rb +4 -0
- data/lib/active_record/associations/has_many_association.rb +6 -5
- data/lib/active_record/associations/has_many_through_association.rb +6 -2
- data/lib/active_record/associations/join_dependency.rb +1 -1
- data/lib/active_record/associations/join_dependency/join_association.rb +1 -1
- data/lib/active_record/associations/preloader.rb +14 -35
- data/lib/active_record/associations/preloader/association.rb +26 -5
- data/lib/active_record/associations/singular_association.rb +3 -3
- data/lib/active_record/associations/through_association.rb +4 -2
- data/lib/active_record/attribute_methods.rb +2 -0
- data/lib/active_record/attribute_methods/dirty.rb +2 -2
- data/lib/active_record/attribute_methods/serialization.rb +24 -5
- data/lib/active_record/attribute_methods/write.rb +22 -14
- data/lib/active_record/autosave_association.rb +40 -35
- data/lib/active_record/base.rb +2 -2
- data/lib/active_record/callbacks.rb +2 -2
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +10 -13
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +1 -0
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +7 -1
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +1 -1
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +8 -6
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +1 -4
- data/lib/active_record/connection_adapters/postgresql/oid.rb +10 -5
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +9 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +11 -6
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +7 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +6 -3
- data/lib/active_record/connection_handling.rb +2 -2
- data/lib/active_record/core.rb +3 -0
- data/lib/active_record/counter_cache.rb +2 -3
- data/lib/active_record/fixtures.rb +1 -1
- data/lib/active_record/gem_version.rb +2 -2
- data/lib/active_record/locking/optimistic.rb +1 -1
- data/lib/active_record/log_subscriber.rb +1 -1
- data/lib/active_record/migration.rb +1 -1
- data/lib/active_record/nested_attributes.rb +2 -2
- data/lib/active_record/null_relation.rb +19 -5
- data/lib/active_record/persistence.rb +8 -8
- data/lib/active_record/railties/databases.rake +3 -2
- data/lib/active_record/reflection.rb +45 -13
- data/lib/active_record/relation.rb +7 -6
- data/lib/active_record/relation/calculations.rb +10 -2
- data/lib/active_record/relation/delegation.rb +2 -2
- data/lib/active_record/relation/finder_methods.rb +1 -1
- data/lib/active_record/relation/merger.rb +10 -2
- data/lib/active_record/relation/predicate_builder.rb +2 -2
- data/lib/active_record/relation/query_methods.rb +2 -2
- data/lib/active_record/scoping/default.rb +3 -3
- data/lib/active_record/store.rb +14 -5
- data/lib/active_record/timestamp.rb +2 -2
- data/lib/active_record/transactions.rb +1 -1
- data/lib/active_record/validations/presence.rb +1 -1
- data/lib/active_record/validations/uniqueness.rb +2 -2
- metadata +27 -35
@@ -37,7 +37,7 @@ module ActiveRecord
|
|
37
37
|
end
|
38
38
|
|
39
39
|
# Given an attributes hash, +instantiate+ returns a new instance of
|
40
|
-
# the appropriate class.
|
40
|
+
# the appropriate class. Accepts only keys as strings.
|
41
41
|
#
|
42
42
|
# For example, +Post.all+ may return Comments, Messages, and Emails
|
43
43
|
# by storing the record's subclass in a +type+ attribute. By calling
|
@@ -46,10 +46,10 @@ module ActiveRecord
|
|
46
46
|
#
|
47
47
|
# See +ActiveRecord::Inheritance#discriminate_class_for_record+ to see
|
48
48
|
# how this "single-table" inheritance mapping is implemented.
|
49
|
-
def instantiate(
|
50
|
-
klass = discriminate_class_for_record(
|
49
|
+
def instantiate(attributes, column_types = {})
|
50
|
+
klass = discriminate_class_for_record(attributes)
|
51
51
|
column_types = klass.decorate_columns(column_types.dup)
|
52
|
-
klass.allocate.init_with('attributes' =>
|
52
|
+
klass.allocate.init_with('attributes' => attributes, 'column_types' => column_types)
|
53
53
|
end
|
54
54
|
|
55
55
|
private
|
@@ -479,24 +479,24 @@ module ActiveRecord
|
|
479
479
|
|
480
480
|
def create_or_update
|
481
481
|
raise ReadOnlyRecord if readonly?
|
482
|
-
result = new_record? ?
|
482
|
+
result = new_record? ? _create_record : _update_record
|
483
483
|
result != false
|
484
484
|
end
|
485
485
|
|
486
486
|
# Updates the associated record with values matching those of the instance attributes.
|
487
487
|
# Returns the number of affected rows.
|
488
|
-
def
|
488
|
+
def _update_record(attribute_names = @attributes.keys)
|
489
489
|
attributes_values = arel_attributes_with_values_for_update(attribute_names)
|
490
490
|
if attributes_values.empty?
|
491
491
|
0
|
492
492
|
else
|
493
|
-
self.class.unscoped.
|
493
|
+
self.class.unscoped._update_record attributes_values, id, id_was
|
494
494
|
end
|
495
495
|
end
|
496
496
|
|
497
497
|
# Creates a record with values matching those of the instance attributes
|
498
498
|
# and returns its id.
|
499
|
-
def
|
499
|
+
def _create_record(attribute_names = @attributes.keys)
|
500
500
|
attributes_values = arel_attributes_with_values_for_create(attribute_names)
|
501
501
|
|
502
502
|
new_id = self.class.unscoped.insert attributes_values
|
@@ -186,7 +186,7 @@ db_namespace = namespace :db do
|
|
186
186
|
|
187
187
|
fixtures_dir = File.join [base_dir, ENV['FIXTURES_DIR']].compact
|
188
188
|
|
189
|
-
(ENV['FIXTURES'] ? ENV['FIXTURES'].split(
|
189
|
+
(ENV['FIXTURES'] ? ENV['FIXTURES'].split(',') : Dir["#{fixtures_dir}/**/*.yml"].map {|f| f[(fixtures_dir.size + 1)..-5] }).each do |fixture_file|
|
190
190
|
ActiveRecord::FixtureSet.create_fixtures(fixtures_dir, fixture_file)
|
191
191
|
end
|
192
192
|
end
|
@@ -268,7 +268,8 @@ db_namespace = namespace :db do
|
|
268
268
|
current_config = ActiveRecord::Tasks::DatabaseTasks.current_config
|
269
269
|
ActiveRecord::Tasks::DatabaseTasks.structure_dump(current_config, filename)
|
270
270
|
|
271
|
-
if ActiveRecord::Base.connection.supports_migrations?
|
271
|
+
if ActiveRecord::Base.connection.supports_migrations? &&
|
272
|
+
ActiveRecord::SchemaMigration.table_exists?
|
272
273
|
File.open(filename, "a") do |f|
|
273
274
|
f.puts ActiveRecord::Base.connection.dump_schema_information
|
274
275
|
f.print "\n"
|
@@ -4,9 +4,9 @@ module ActiveRecord
|
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
6
|
included do
|
7
|
-
class_attribute :
|
7
|
+
class_attribute :_reflections
|
8
8
|
class_attribute :aggregate_reflections
|
9
|
-
self.
|
9
|
+
self._reflections = {}
|
10
10
|
self.aggregate_reflections = {}
|
11
11
|
end
|
12
12
|
|
@@ -22,7 +22,7 @@ module ActiveRecord
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def self.add_reflection(ar, name, reflection)
|
25
|
-
ar.
|
25
|
+
ar._reflections = ar._reflections.merge(name => reflection)
|
26
26
|
end
|
27
27
|
|
28
28
|
def self.add_aggregate_reflection(ar, name, reflection)
|
@@ -51,6 +51,24 @@ module ActiveRecord
|
|
51
51
|
aggregate_reflections[aggregation]
|
52
52
|
end
|
53
53
|
|
54
|
+
# Returns a Hash of name of the reflection as the key and a AssociationReflection as the value.
|
55
|
+
#
|
56
|
+
# Account.reflections # => {balance: AggregateReflection}
|
57
|
+
#
|
58
|
+
# @api public
|
59
|
+
def reflections
|
60
|
+
ref = {}
|
61
|
+
_reflections.each do |name, reflection|
|
62
|
+
parent_name, parent_reflection = reflection.parent_reflection
|
63
|
+
if parent_name
|
64
|
+
ref[parent_name] = parent_reflection
|
65
|
+
else
|
66
|
+
ref[name] = reflection
|
67
|
+
end
|
68
|
+
end
|
69
|
+
ref
|
70
|
+
end
|
71
|
+
|
54
72
|
# Returns an array of AssociationReflection objects for all the
|
55
73
|
# associations in the class. If you only want to reflect on a certain
|
56
74
|
# association type, pass in the symbol (<tt>:has_many</tt>, <tt>:has_one</tt>,
|
@@ -61,6 +79,7 @@ module ActiveRecord
|
|
61
79
|
# Account.reflect_on_all_associations # returns an array of all associations
|
62
80
|
# Account.reflect_on_all_associations(:has_many) # returns an array of all has_many associations
|
63
81
|
#
|
82
|
+
# @api public
|
64
83
|
def reflect_on_all_associations(macro = nil)
|
65
84
|
association_reflections = reflections.values
|
66
85
|
macro ? association_reflections.select { |reflection| reflection.macro == macro } : association_reflections
|
@@ -71,11 +90,19 @@ module ActiveRecord
|
|
71
90
|
# Account.reflect_on_association(:owner) # returns the owner AssociationReflection
|
72
91
|
# Invoice.reflect_on_association(:line_items).macro # returns :has_many
|
73
92
|
#
|
93
|
+
# @api public
|
74
94
|
def reflect_on_association(association)
|
75
95
|
reflections[association]
|
76
96
|
end
|
77
97
|
|
98
|
+
# @api private
|
99
|
+
def _reflect_on_association(association) #:nodoc:
|
100
|
+
_reflections[association]
|
101
|
+
end
|
102
|
+
|
78
103
|
# Returns an array of AssociationReflection objects for all associations which have <tt>:autosave</tt> enabled.
|
104
|
+
#
|
105
|
+
# @api public
|
79
106
|
def reflect_on_all_autosave_associations
|
80
107
|
reflections.values.select { |reflection| reflection.options[:autosave] }
|
81
108
|
end
|
@@ -127,6 +154,10 @@ module ActiveRecord
|
|
127
154
|
def autosave=(autosave)
|
128
155
|
@automatic_inverse_of = false
|
129
156
|
@options[:autosave] = autosave
|
157
|
+
_, parent_reflection = self.parent_reflection
|
158
|
+
if parent_reflection
|
159
|
+
parent_reflection.autosave = autosave
|
160
|
+
end
|
130
161
|
end
|
131
162
|
|
132
163
|
# Returns the class for the macro.
|
@@ -191,10 +222,11 @@ module ActiveRecord
|
|
191
222
|
end
|
192
223
|
|
193
224
|
attr_reader :type, :foreign_type
|
225
|
+
attr_accessor :parent_reflection # [:name, Reflection]
|
194
226
|
|
195
227
|
def initialize(macro, name, scope, options, active_record)
|
196
228
|
super
|
197
|
-
@collection = :has_many
|
229
|
+
@collection = [:has_many, :has_and_belongs_to_many].include?(macro)
|
198
230
|
@automatic_inverse_of = nil
|
199
231
|
@type = options[:as] && "#{options[:as]}_type"
|
200
232
|
@foreign_type = options[:foreign_type] || "#{name}_type"
|
@@ -297,12 +329,12 @@ module ActiveRecord
|
|
297
329
|
def inverse_of
|
298
330
|
return unless inverse_name
|
299
331
|
|
300
|
-
@inverse_of ||= klass.
|
332
|
+
@inverse_of ||= klass._reflect_on_association inverse_name
|
301
333
|
end
|
302
334
|
|
303
335
|
def polymorphic_inverse_of(associated_class)
|
304
336
|
if has_inverse?
|
305
|
-
if inverse_relationship = associated_class.
|
337
|
+
if inverse_relationship = associated_class._reflect_on_association(options[:inverse_of])
|
306
338
|
inverse_relationship
|
307
339
|
else
|
308
340
|
raise InverseOfAssociationNotFoundError.new(self, associated_class)
|
@@ -403,7 +435,7 @@ module ActiveRecord
|
|
403
435
|
inverse_name = ActiveSupport::Inflector.underscore(active_record.name).to_sym
|
404
436
|
|
405
437
|
begin
|
406
|
-
reflection = klass.
|
438
|
+
reflection = klass._reflect_on_association(inverse_name)
|
407
439
|
rescue NameError
|
408
440
|
# Give up: we couldn't compute the klass type so we won't be able
|
409
441
|
# to find any associations either.
|
@@ -449,9 +481,9 @@ module ActiveRecord
|
|
449
481
|
end
|
450
482
|
|
451
483
|
def derive_class_name
|
452
|
-
class_name = name.to_s
|
484
|
+
class_name = name.to_s
|
453
485
|
class_name = class_name.singularize if collection?
|
454
|
-
class_name
|
486
|
+
class_name.camelize
|
455
487
|
end
|
456
488
|
|
457
489
|
def derive_foreign_key
|
@@ -502,7 +534,7 @@ module ActiveRecord
|
|
502
534
|
# # => <ActiveRecord::Reflection::AssociationReflection: @macro=:belongs_to, @name=:tag, @active_record=Tagging, @plural_name="tags">
|
503
535
|
#
|
504
536
|
def source_reflection
|
505
|
-
through_reflection.klass.
|
537
|
+
through_reflection.klass._reflect_on_association(source_reflection_name)
|
506
538
|
end
|
507
539
|
|
508
540
|
# Returns the AssociationReflection object specified in the <tt>:through</tt> option
|
@@ -518,7 +550,7 @@ module ActiveRecord
|
|
518
550
|
# # => <ActiveRecord::Reflection::AssociationReflection: @macro=:has_many, @name=:taggings, @active_record=Post, @plural_name="taggings">
|
519
551
|
#
|
520
552
|
def through_reflection
|
521
|
-
active_record.
|
553
|
+
active_record._reflect_on_association(options[:through])
|
522
554
|
end
|
523
555
|
|
524
556
|
# Returns an array of reflections which are involved in this association. Each item in the
|
@@ -621,11 +653,11 @@ module ActiveRecord
|
|
621
653
|
end
|
622
654
|
|
623
655
|
def source_reflection_name # :nodoc:
|
624
|
-
return @source_reflection_name if @source_reflection_name
|
656
|
+
return @source_reflection_name.to_sym if @source_reflection_name
|
625
657
|
|
626
658
|
names = [name.to_s.singularize, name].collect { |n| n.to_sym }.uniq
|
627
659
|
names = names.find_all { |n|
|
628
|
-
through_reflection.klass.
|
660
|
+
through_reflection.klass._reflect_on_association(n)
|
629
661
|
}
|
630
662
|
|
631
663
|
if names.length > 1
|
@@ -70,7 +70,7 @@ module ActiveRecord
|
|
70
70
|
binds)
|
71
71
|
end
|
72
72
|
|
73
|
-
def
|
73
|
+
def _update_record(values, id, id_was) # :nodoc:
|
74
74
|
substitutes, binds = substitute_values values
|
75
75
|
um = @klass.unscoped.where(@klass.arel_table[@klass.primary_key].eq(id_was || id)).arel.compile_update(substitutes, @klass.primary_key)
|
76
76
|
|
@@ -238,7 +238,7 @@ module ActiveRecord
|
|
238
238
|
|
239
239
|
# Returns size of the records.
|
240
240
|
def size
|
241
|
-
loaded? ? @records.length : count
|
241
|
+
loaded? ? @records.length : count(:all)
|
242
242
|
end
|
243
243
|
|
244
244
|
# Returns true if there are no records.
|
@@ -248,8 +248,7 @@ module ActiveRecord
|
|
248
248
|
if limit_value == 0
|
249
249
|
true
|
250
250
|
else
|
251
|
-
|
252
|
-
c = count
|
251
|
+
c = count(:all)
|
253
252
|
c.respond_to?(:zero?) ? c.zero? : c.empty?
|
254
253
|
end
|
255
254
|
end
|
@@ -529,9 +528,9 @@ module ActiveRecord
|
|
529
528
|
#
|
530
529
|
# User.where(name: 'Oscar').where_values_hash
|
531
530
|
# # => {name: "Oscar"}
|
532
|
-
def where_values_hash
|
531
|
+
def where_values_hash(relation_table_name = table_name)
|
533
532
|
equalities = where_values.grep(Arel::Nodes::Equality).find_all { |node|
|
534
|
-
node.left.relation.name ==
|
533
|
+
node.left.relation.name == relation_table_name
|
535
534
|
}
|
536
535
|
|
537
536
|
binds = Hash[bind_values.find_all(&:first).map { |column, v| [column.name, v] }]
|
@@ -570,6 +569,8 @@ module ActiveRecord
|
|
570
569
|
# Compares two relations for equality.
|
571
570
|
def ==(other)
|
572
571
|
case other
|
572
|
+
when Associations::CollectionProxy, AssociationRelation
|
573
|
+
self == other.to_a
|
573
574
|
when Relation
|
574
575
|
other.to_sql == to_sql
|
575
576
|
when Array
|
@@ -19,6 +19,14 @@ module ActiveRecord
|
|
19
19
|
#
|
20
20
|
# Person.group(:city).count
|
21
21
|
# # => { 'Rome' => 5, 'Paris' => 3 }
|
22
|
+
#
|
23
|
+
# If +count+ is used with +select+, it will count the selected columns:
|
24
|
+
#
|
25
|
+
# Person.select(:age).count
|
26
|
+
# # => counts the number of different age values
|
27
|
+
#
|
28
|
+
# Note: not all valid +select+ expressions are valid +count+ expressions. The specifics differ
|
29
|
+
# between databases. In invalid cases, an error from the databsae is thrown.
|
22
30
|
def count(column_name = nil, options = {})
|
23
31
|
# TODO: Remove options argument as soon we remove support to
|
24
32
|
# activerecord-deprecated_finders.
|
@@ -188,7 +196,7 @@ module ActiveRecord
|
|
188
196
|
private
|
189
197
|
|
190
198
|
def has_include?(column_name)
|
191
|
-
eager_loading? || (includes_values.present? && (column_name || references_eager_loaded_tables?))
|
199
|
+
eager_loading? || (includes_values.present? && ((column_name && column_name != :all) || references_eager_loaded_tables?))
|
192
200
|
end
|
193
201
|
|
194
202
|
def perform_calculation(operation, column_name, options = {})
|
@@ -265,7 +273,7 @@ module ActiveRecord
|
|
265
273
|
group_attrs = group_values
|
266
274
|
|
267
275
|
if group_attrs.first.respond_to?(:to_sym)
|
268
|
-
association = @klass.
|
276
|
+
association = @klass._reflect_on_association(group_attrs.first.to_sym)
|
269
277
|
associated = group_attrs.size == 1 && association && association.macro == :belongs_to # only count belongs_to associations
|
270
278
|
group_fields = Array(associated ? association.foreign_key : group_attrs)
|
271
279
|
else
|
@@ -40,10 +40,10 @@ module ActiveRecord
|
|
40
40
|
BLACKLISTED_ARRAY_METHODS = [
|
41
41
|
:compact!, :flatten!, :reject!, :reverse!, :rotate!, :map!,
|
42
42
|
:shuffle!, :slice!, :sort!, :sort_by!, :delete_if,
|
43
|
-
:keep_if, :pop, :shift, :delete_at, :compact
|
43
|
+
:keep_if, :pop, :shift, :delete_at, :compact, :select!
|
44
44
|
].to_set # :nodoc:
|
45
45
|
|
46
|
-
delegate :to_xml, :to_yaml, :length, :collect, :map, :each, :all?, :include?, :to_ary, to: :to_a
|
46
|
+
delegate :to_xml, :to_yaml, :length, :collect, :map, :each, :all?, :include?, :to_ary, :join, to: :to_a
|
47
47
|
|
48
48
|
delegate :table_name, :quoted_table_name, :primary_key, :quoted_primary_key,
|
49
49
|
:connection, :columns_hash, :to => :klass
|
@@ -240,7 +240,7 @@ module ActiveRecord
|
|
240
240
|
# If no order is defined it will order by primary key.
|
241
241
|
#
|
242
242
|
# Person.forty_two # returns the forty-second object fetched by SELECT * FROM people
|
243
|
-
# Person.offset(3).forty_two # returns the
|
243
|
+
# Person.offset(3).forty_two # returns the forty-second object from OFFSET 3 (which is OFFSET 44)
|
244
244
|
# Person.where(["user_name = :u", { u: user_name }]).forty_two
|
245
245
|
def forty_two
|
246
246
|
find_nth(:forty_two, offset_value ? offset_value + 41 : 41)
|
@@ -30,6 +30,8 @@ module ActiveRecord
|
|
30
30
|
else
|
31
31
|
other.joins!(*v)
|
32
32
|
end
|
33
|
+
elsif k == :select
|
34
|
+
other._select!(v)
|
33
35
|
else
|
34
36
|
other.send("#{k}!", v)
|
35
37
|
end
|
@@ -62,7 +64,13 @@ module ActiveRecord
|
|
62
64
|
# expensive), most of the time the value is going to be `nil` or `.blank?`, the only catch is that
|
63
65
|
# `false.blank?` returns `true`, so there needs to be an extra check so that explicit `false` values
|
64
66
|
# don't fall through the cracks.
|
65
|
-
|
67
|
+
unless value.nil? || (value.blank? && false != value)
|
68
|
+
if name == :select
|
69
|
+
relation._select!(*value)
|
70
|
+
else
|
71
|
+
relation.send("#{name}!", *value)
|
72
|
+
end
|
73
|
+
end
|
66
74
|
end
|
67
75
|
|
68
76
|
merge_multi_values
|
@@ -149,7 +157,7 @@ module ActiveRecord
|
|
149
157
|
def filter_binds(lhs_binds, removed_wheres)
|
150
158
|
return lhs_binds if removed_wheres.empty?
|
151
159
|
|
152
|
-
set = Set.new removed_wheres.map { |x| x.left.name }
|
160
|
+
set = Set.new removed_wheres.map { |x| x.left.name.to_s }
|
153
161
|
lhs_binds.dup.delete_if { |col,_| set.include? col.name }
|
154
162
|
end
|
155
163
|
|
@@ -26,7 +26,7 @@ module ActiveRecord
|
|
26
26
|
queries << '1=0'
|
27
27
|
else
|
28
28
|
table = Arel::Table.new(column, default_table.engine)
|
29
|
-
association = klass.
|
29
|
+
association = klass._reflect_on_association(column.to_sym)
|
30
30
|
|
31
31
|
value.each do |k, v|
|
32
32
|
queries.concat expand(association && association.klass, table, k, v)
|
@@ -55,7 +55,7 @@ module ActiveRecord
|
|
55
55
|
#
|
56
56
|
# For polymorphic relationships, find the foreign key and type:
|
57
57
|
# PriceEstimate.where(estimate_of: treasure)
|
58
|
-
if klass && reflection = klass.
|
58
|
+
if klass && reflection = klass._reflect_on_association(column.to_sym)
|
59
59
|
if reflection.polymorphic? && base_class = polymorphic_base_class_from_value(value)
|
60
60
|
queries << build(table[reflection.foreign_type], base_class)
|
61
61
|
end
|
@@ -235,11 +235,11 @@ module ActiveRecord
|
|
235
235
|
to_a.select { |*block_args| yield(*block_args) }
|
236
236
|
else
|
237
237
|
raise ArgumentError, 'Call this with at least one field' if fields.empty?
|
238
|
-
spawn.
|
238
|
+
spawn._select!(*fields)
|
239
239
|
end
|
240
240
|
end
|
241
241
|
|
242
|
-
def
|
242
|
+
def _select!(*fields) # :nodoc:
|
243
243
|
fields.flatten!
|
244
244
|
fields.map! do |field|
|
245
245
|
klass.attribute_alias?(field) ? klass.attribute_alias(field) : field
|
@@ -93,14 +93,14 @@ module ActiveRecord
|
|
93
93
|
self.default_scopes += [scope]
|
94
94
|
end
|
95
95
|
|
96
|
-
def build_default_scope # :nodoc:
|
96
|
+
def build_default_scope(base_rel = relation) # :nodoc:
|
97
97
|
if !Base.is_a?(method(:default_scope).owner)
|
98
98
|
# The user has defined their own default scope method, so call that
|
99
99
|
evaluate_default_scope { default_scope }
|
100
100
|
elsif default_scopes.any?
|
101
101
|
evaluate_default_scope do
|
102
|
-
default_scopes.inject(
|
103
|
-
default_scope.merge(
|
102
|
+
default_scopes.inject(base_rel) do |default_scope, scope|
|
103
|
+
default_scope.merge(base_rel.scoping { scope.call })
|
104
104
|
end
|
105
105
|
end
|
106
106
|
end
|
data/lib/active_record/store.rb
CHANGED
@@ -66,8 +66,9 @@ module ActiveRecord
|
|
66
66
|
extend ActiveSupport::Concern
|
67
67
|
|
68
68
|
included do
|
69
|
-
|
70
|
-
|
69
|
+
class << self
|
70
|
+
attr_accessor :local_stored_attributes
|
71
|
+
end
|
71
72
|
end
|
72
73
|
|
73
74
|
module ClassMethods
|
@@ -93,9 +94,9 @@ module ActiveRecord
|
|
93
94
|
|
94
95
|
# assign new store attribute and create new hash to ensure that each class in the hierarchy
|
95
96
|
# has its own hash of stored attributes.
|
96
|
-
self.
|
97
|
-
self.
|
98
|
-
self.
|
97
|
+
self.local_stored_attributes ||= {}
|
98
|
+
self.local_stored_attributes[store_attribute] ||= []
|
99
|
+
self.local_stored_attributes[store_attribute] |= keys
|
99
100
|
end
|
100
101
|
|
101
102
|
def _store_accessors_module
|
@@ -105,6 +106,14 @@ module ActiveRecord
|
|
105
106
|
mod
|
106
107
|
end
|
107
108
|
end
|
109
|
+
|
110
|
+
def stored_attributes
|
111
|
+
parent = superclass.respond_to?(:stored_attributes) ? superclass.stored_attributes : {}
|
112
|
+
if self.local_stored_attributes
|
113
|
+
parent.merge!(self.local_stored_attributes) { |k, a, b| a | b }
|
114
|
+
end
|
115
|
+
parent
|
116
|
+
end
|
108
117
|
end
|
109
118
|
|
110
119
|
protected
|