aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib')
-rw-r--r--activerecord/lib/active_record/association_relation.rb2
-rw-r--r--activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb3
-rw-r--r--activerecord/lib/active_record/associations/collection_proxy.rb4
-rw-r--r--activerecord/lib/active_record/associations/singular_association.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb2
-rw-r--r--activerecord/lib/active_record/null_relation.rb2
-rw-r--r--activerecord/lib/active_record/relation.rb32
-rw-r--r--activerecord/lib/active_record/relation/batches.rb2
-rw-r--r--activerecord/lib/active_record/relation/batches/batch_enumerator.rb2
-rw-r--r--activerecord/lib/active_record/relation/delegation.rb3
-rw-r--r--activerecord/lib/active_record/relation/finder_methods.rb6
-rw-r--r--activerecord/lib/active_record/relation/spawn_methods.rb2
-rw-r--r--activerecord/lib/active_record/validations/absence.rb2
-rw-r--r--activerecord/lib/active_record/validations/length.rb2
-rw-r--r--activerecord/lib/active_record/validations/presence.rb2
-rw-r--r--activerecord/lib/active_record/validations/uniqueness.rb11
16 files changed, 45 insertions, 34 deletions
diff --git a/activerecord/lib/active_record/association_relation.rb b/activerecord/lib/active_record/association_relation.rb
index ee0bb8fafe..c18e88e4cf 100644
--- a/activerecord/lib/active_record/association_relation.rb
+++ b/activerecord/lib/active_record/association_relation.rb
@@ -10,7 +10,7 @@ module ActiveRecord
end
def ==(other)
- other == to_a
+ other == records
end
def build(*args, &block)
diff --git a/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb b/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb
index b888148841..5fbd79d118 100644
--- a/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb
+++ b/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb
@@ -76,6 +76,9 @@ module ActiveRecord::Associations::Builder # :nodoc:
left_model.retrieve_connection
end
+ def self.primary_key
+ false
+ end
}
join_model.name = "HABTM_#{association_name.to_s.camelize}"
diff --git a/activerecord/lib/active_record/associations/collection_proxy.rb b/activerecord/lib/active_record/associations/collection_proxy.rb
index 2a9627a474..b9aed05135 100644
--- a/activerecord/lib/active_record/associations/collection_proxy.rb
+++ b/activerecord/lib/active_record/associations/collection_proxy.rb
@@ -979,6 +979,10 @@ module ActiveRecord
end
alias_method :to_a, :to_ary
+ def records # :nodoc:
+ load_target
+ end
+
# Adds one or more +records+ to the collection by setting their foreign keys
# to the association's primary key. Returns +self+, so several appends may be
# chained together.
diff --git a/activerecord/lib/active_record/associations/singular_association.rb b/activerecord/lib/active_record/associations/singular_association.rb
index c7cc48ba16..f913f0852a 100644
--- a/activerecord/lib/active_record/associations/singular_association.rb
+++ b/activerecord/lib/active_record/associations/singular_association.rb
@@ -45,7 +45,7 @@ module ActiveRecord
end
def get_records
- return scope.limit(1).to_a if skip_statement_cache?
+ return scope.limit(1).records if skip_statement_cache?
conn = klass.connection
sc = reflection.association_scope_cache(conn, owner) do
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb b/activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb
index 6aa264d766..6f2e03b370 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb
@@ -118,7 +118,7 @@ module ActiveRecord
alias :exec_update :exec_delete
def sql_for_insert(sql, pk, id_value, sequence_name, binds) # :nodoc:
- unless pk
+ if pk.nil?
# Extract the table from the insert sql. Yuck.
table_ref = extract_table_ref_from_insert_sql(sql)
pk = primary_key(table_ref) if table_ref
diff --git a/activerecord/lib/active_record/null_relation.rb b/activerecord/lib/active_record/null_relation.rb
index 0b500346bc..1ab4e0404f 100644
--- a/activerecord/lib/active_record/null_relation.rb
+++ b/activerecord/lib/active_record/null_relation.rb
@@ -1,7 +1,7 @@
module ActiveRecord
module NullRelation # :nodoc:
def exec_queries
- @records = []
+ @records = [].freeze
end
def pluck(*column_names)
diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb
index 7e842668c6..09afdc6c69 100644
--- a/activerecord/lib/active_record/relation.rb
+++ b/activerecord/lib/active_record/relation.rb
@@ -253,17 +253,21 @@ module ActiveRecord
# Converts relation objects to Array.
def to_a
+ records.dup
+ end
+
+ def records # :nodoc:
load
@records
end
# Serializes the relation objects Array.
def encode_with(coder)
- coder.represent_seq(nil, to_a)
+ coder.represent_seq(nil, records)
end
def as_json(options = nil) #:nodoc:
- to_a.as_json(options)
+ records.as_json(options)
end
# Returns size of the records.
@@ -298,13 +302,13 @@ module ActiveRecord
# Returns true if there is exactly one record.
def one?
return super if block_given?
- limit_value ? to_a.one? : size == 1
+ limit_value ? records.one? : size == 1
end
# Returns true if there is more than one record.
def many?
return super if block_given?
- limit_value ? to_a.many? : size > 1
+ limit_value ? records.many? : size > 1
end
# Returns a cache key that can be used to identify the records fetched by
@@ -418,7 +422,7 @@ module ActiveRecord
if id.is_a?(Array)
id.map.with_index { |one_id, idx| update(one_id, attributes[idx]) }
elsif id == :all
- to_a.each { |record| record.update(attributes) }
+ records.each { |record| record.update(attributes) }
else
if ActiveRecord::Base === id
id = id.id
@@ -457,7 +461,7 @@ module ActiveRecord
MESSAGE
where(conditions).destroy_all
else
- to_a.each(&:destroy).tap { reset }
+ records.each(&:destroy).tap { reset }
end
end
@@ -587,7 +591,7 @@ module ActiveRecord
def reset
@last = @to_sql = @order_clause = @scope_for_create = @arel = @loaded = nil
@should_eager_load = @join_dependency = nil
- @records = []
+ @records = [].freeze
@offsets = {}
self
end
@@ -654,21 +658,21 @@ module ActiveRecord
def ==(other)
case other
when Associations::CollectionProxy, AssociationRelation
- self == other.to_a
+ self == other.records
when Relation
other.to_sql == to_sql
when Array
- to_a == other
+ records == other
end
end
def pretty_print(q)
- q.pp(self.to_a)
+ q.pp(self.records)
end
# Returns true if relation is blank.
def blank?
- to_a.blank?
+ records.blank?
end
def values
@@ -676,7 +680,7 @@ module ActiveRecord
end
def inspect
- entries = to_a.take([limit_value, 11].compact.min).map!(&:inspect)
+ entries = records.take([limit_value, 11].compact.min).map!(&:inspect)
entries[10] = '...' if entries.size == 11
"#<#{self.class.name} [#{entries.join(', ')}]>"
@@ -685,14 +689,14 @@ module ActiveRecord
protected
def load_records(records)
- @records = records
+ @records = records.freeze
@loaded = true
end
private
def exec_queries
- @records = eager_loading? ? find_with_associations : @klass.find_by_sql(arel, bound_attributes)
+ @records = eager_loading? ? find_with_associations.freeze : @klass.find_by_sql(arel, bound_attributes).freeze
preload = preload_values
preload += includes_values unless eager_loading?
diff --git a/activerecord/lib/active_record/relation/batches.rb b/activerecord/lib/active_record/relation/batches.rb
index de005e2810..243ef0eae9 100644
--- a/activerecord/lib/active_record/relation/batches.rb
+++ b/activerecord/lib/active_record/relation/batches.rb
@@ -187,7 +187,7 @@ module ActiveRecord
loop do
if load
- records = batch_relation.to_a
+ records = batch_relation.records
ids = records.map(&:id)
yielded_relation = self.where(primary_key => ids)
yielded_relation.load_records(records)
diff --git a/activerecord/lib/active_record/relation/batches/batch_enumerator.rb b/activerecord/lib/active_record/relation/batches/batch_enumerator.rb
index c6e39814dd..13393dc605 100644
--- a/activerecord/lib/active_record/relation/batches/batch_enumerator.rb
+++ b/activerecord/lib/active_record/relation/batches/batch_enumerator.rb
@@ -35,7 +35,7 @@ module ActiveRecord
return to_enum(:each_record) unless block_given?
@relation.to_enum(:in_batches, of: @of, start: @start, finish: @finish, load: true).each do |relation|
- relation.to_a.each { |record| yield record }
+ relation.records.each { |record| yield record }
end
end
diff --git a/activerecord/lib/active_record/relation/delegation.rb b/activerecord/lib/active_record/relation/delegation.rb
index e4e5d63006..f2578f5f96 100644
--- a/activerecord/lib/active_record/relation/delegation.rb
+++ b/activerecord/lib/active_record/relation/delegation.rb
@@ -37,7 +37,8 @@ module ActiveRecord
# for each different klass, and the delegations are compiled into that subclass only.
delegate :to_xml, :to_yaml, :length, :collect, :map, :each, :all?, :include?, :to_ary, :join,
- :[], :&, :|, :+, :-, :sample, :shuffle, :reverse, :compact, to: :to_a
+ :[], :&, :|, :+, :-, :sample, :reverse, :compact, :in_groups, :in_groups_of,
+ :shuffle, :split, to: :records
delegate :table_name, :quoted_table_name, :primary_key, :quoted_primary_key,
:connection, :columns_hash, :to => :klass
diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb
index 16563515f6..0037398554 100644
--- a/activerecord/lib/active_record/relation/finder_methods.rb
+++ b/activerecord/lib/active_record/relation/finder_methods.rb
@@ -506,7 +506,7 @@ module ActiveRecord
def find_some_ordered(ids)
ids = ids.slice(offset_value || 0, limit_value || ids.size) || []
- result = except(:limit, :offset).where(primary_key => ids).to_a
+ result = except(:limit, :offset).where(primary_key => ids).records
if result.size == ids.size
pk_type = @klass.type_for_attribute(primary_key)
@@ -522,7 +522,7 @@ module ActiveRecord
if loaded?
@records.first
else
- @take ||= limit(1).to_a.first
+ @take ||= limit(1).records.first
end
end
@@ -573,7 +573,7 @@ module ActiveRecord
end
def find_last(limit)
- limit ? to_a.last(limit) : to_a.last
+ limit ? records.last(limit) : records.last
end
end
end
diff --git a/activerecord/lib/active_record/relation/spawn_methods.rb b/activerecord/lib/active_record/relation/spawn_methods.rb
index 67d7f83cb4..d5c18a2a4a 100644
--- a/activerecord/lib/active_record/relation/spawn_methods.rb
+++ b/activerecord/lib/active_record/relation/spawn_methods.rb
@@ -29,7 +29,7 @@ module ActiveRecord
# This is mainly intended for sharing common conditions between multiple associations.
def merge(other)
if other.is_a?(Array)
- to_a & other
+ records & other
elsif other
spawn.merge!(other)
else
diff --git a/activerecord/lib/active_record/validations/absence.rb b/activerecord/lib/active_record/validations/absence.rb
index 2e19e6dc5c..376d743c92 100644
--- a/activerecord/lib/active_record/validations/absence.rb
+++ b/activerecord/lib/active_record/validations/absence.rb
@@ -2,7 +2,7 @@ module ActiveRecord
module Validations
class AbsenceValidator < ActiveModel::Validations::AbsenceValidator # :nodoc:
def validate_each(record, attribute, association_or_value)
- return unless should_validate?(record)
+ return unless should_validate?(record) || unknown_attribute?(record, attribute)
if record.class._reflect_on_association(attribute)
association_or_value = Array.wrap(association_or_value).reject(&:marked_for_destruction?)
end
diff --git a/activerecord/lib/active_record/validations/length.rb b/activerecord/lib/active_record/validations/length.rb
index 69e048eef1..fe34e4875c 100644
--- a/activerecord/lib/active_record/validations/length.rb
+++ b/activerecord/lib/active_record/validations/length.rb
@@ -2,7 +2,7 @@ module ActiveRecord
module Validations
class LengthValidator < ActiveModel::Validations::LengthValidator # :nodoc:
def validate_each(record, attribute, association_or_value)
- return unless should_validate?(record) || associations_are_dirty?(record)
+ return unless should_validate?(record) || unknown_attribute?(record, attribute) || associations_are_dirty?(record)
if association_or_value.respond_to?(:loaded?) && association_or_value.loaded?
association_or_value = association_or_value.target.reject(&:marked_for_destruction?)
end
diff --git a/activerecord/lib/active_record/validations/presence.rb b/activerecord/lib/active_record/validations/presence.rb
index 7e85ed43ac..e34d2d70ab 100644
--- a/activerecord/lib/active_record/validations/presence.rb
+++ b/activerecord/lib/active_record/validations/presence.rb
@@ -2,7 +2,7 @@ module ActiveRecord
module Validations
class PresenceValidator < ActiveModel::Validations::PresenceValidator # :nodoc:
def validate_each(record, attribute, association_or_value)
- return unless should_validate?(record)
+ return unless should_validate?(record) || unknown_attribute?(record, attribute)
if record.class._reflect_on_association(attribute)
association_or_value = Array.wrap(association_or_value).reject(&:marked_for_destruction?)
end
diff --git a/activerecord/lib/active_record/validations/uniqueness.rb b/activerecord/lib/active_record/validations/uniqueness.rb
index f0aa4521b5..88c272657f 100644
--- a/activerecord/lib/active_record/validations/uniqueness.rb
+++ b/activerecord/lib/active_record/validations/uniqueness.rb
@@ -57,14 +57,13 @@ module ActiveRecord
value = value.attributes[reflection.klass.primary_key] unless value.nil?
end
- attribute_name = attribute.to_s
-
# the attribute may be an aliased attribute
- if klass.attribute_aliases[attribute_name]
- attribute = klass.attribute_aliases[attribute_name]
- attribute_name = attribute.to_s
+ if klass.attribute_alias?(attribute)
+ attribute = klass.attribute_alias(attribute)
end
+ attribute_name = attribute.to_s
+
column = klass.columns_hash[attribute_name]
cast_type = klass.type_for_attribute(attribute_name)
value = cast_type.serialize(value)
@@ -82,7 +81,7 @@ module ActiveRecord
if value.nil?
klass.unscoped.where(comparison)
else
- bind = Relation::QueryAttribute.new(attribute.to_s, value, Type::Value.new)
+ bind = Relation::QueryAttribute.new(attribute_name, value, Type::Value.new)
klass.unscoped.where(comparison, bind)
end
rescue RangeError