diff options
Diffstat (limited to 'activerecord/lib/active_record/relation/finder_methods.rb')
-rw-r--r-- | activerecord/lib/active_record/relation/finder_methods.rb | 216 |
1 files changed, 102 insertions, 114 deletions
diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb index 5e456452e9..6663bdb244 100644 --- a/activerecord/lib/active_record/relation/finder_methods.rb +++ b/activerecord/lib/active_record/relation/finder_methods.rb @@ -152,14 +152,6 @@ module ActiveRecord result = result.reverse_order! limit ? result.reverse : result.first - rescue ActiveRecord::IrreversibleOrderError - ActiveSupport::Deprecation.warn(<<-WARNING.squish) - Finding a last element by loading the relation when SQL ORDER - can not be reversed is deprecated. - Rails 5.1 will raise ActiveRecord::IrreversibleOrderError in this case. - Please call `to_a.last` if you still want to load the relation. - WARNING - find_last(limit) end # Same as #last but raises ActiveRecord::RecordNotFound if no record @@ -309,8 +301,7 @@ module ActiveRecord # Person.exists? def exists?(conditions = :none) if Base === conditions - conditions = conditions.id - ActiveSupport::Deprecation.warn(<<-MSG.squish) + raise ArgumentError, <<-MSG.squish You are passing an instance of ActiveRecord::Base to `exists?`. Please pass the id of the object by calling `.id`. MSG @@ -439,143 +430,140 @@ module ActiveRecord reflections.none?(&:collection?) end - protected + private - def find_with_ids(*ids) - raise UnknownPrimaryKey.new(@klass) if primary_key.nil? + def find_with_ids(*ids) + raise UnknownPrimaryKey.new(@klass) if primary_key.nil? - expects_array = ids.first.kind_of?(Array) - return ids.first if expects_array && ids.first.empty? + expects_array = ids.first.kind_of?(Array) + return ids.first if expects_array && ids.first.empty? - ids = ids.flatten.compact.uniq + ids = ids.flatten.compact.uniq - case ids.size - when 0 - raise RecordNotFound, "Couldn't find #{@klass.name} without an ID" - when 1 - result = find_one(ids.first) - expects_array ? [ result ] : result - else - find_some(ids) + case ids.size + when 0 + raise RecordNotFound, "Couldn't find #{@klass.name} without an ID" + when 1 + result = find_one(ids.first) + expects_array ? [ result ] : result + else + find_some(ids) + end + rescue ::RangeError + raise RecordNotFound, "Couldn't find #{@klass.name} with an out of range ID" end - rescue ::RangeError - raise RecordNotFound, "Couldn't find #{@klass.name} with an out of range ID" - end - def find_one(id) - if ActiveRecord::Base === id - id = id.id - ActiveSupport::Deprecation.warn(<<-MSG.squish) - You are passing an instance of ActiveRecord::Base to `find`. - Please pass the id of the object by calling `.id`. - MSG - end + def find_one(id) + if ActiveRecord::Base === id + raise ArgumentError, <<-MSG.squish + You are passing an instance of ActiveRecord::Base to `find`. + Please pass the id of the object by calling `.id`. + MSG + end - relation = where(primary_key => id) - record = relation.take + relation = where(primary_key => id) + record = relation.take - raise_record_not_found_exception!(id, 0, 1) unless record + raise_record_not_found_exception!(id, 0, 1) unless record - record - end + record + end - def find_some(ids) - return find_some_ordered(ids) unless order_values.present? + def find_some(ids) + return find_some_ordered(ids) unless order_values.present? - result = where(primary_key => ids).to_a + result = where(primary_key => ids).to_a - expected_size = - if limit_value && ids.size > limit_value - limit_value - else - ids.size - end + expected_size = + if limit_value && ids.size > limit_value + limit_value + else + ids.size + end - # 11 ids with limit 3, offset 9 should give 2 results. - if offset_value && (ids.size - offset_value < expected_size) - expected_size = ids.size - offset_value - end + # 11 ids with limit 3, offset 9 should give 2 results. + if offset_value && (ids.size - offset_value < expected_size) + expected_size = ids.size - offset_value + end - if result.size == expected_size - result - else - raise_record_not_found_exception!(ids, result.size, expected_size) + if result.size == expected_size + result + else + raise_record_not_found_exception!(ids, result.size, expected_size) + end end - end - def find_some_ordered(ids) - ids = ids.slice(offset_value || 0, limit_value || ids.size) || [] + def find_some_ordered(ids) + ids = ids.slice(offset_value || 0, limit_value || ids.size) || [] - result = except(:limit, :offset).where(primary_key => ids).records + result = except(:limit, :offset).where(primary_key => ids).records - if result.size == ids.size - pk_type = @klass.type_for_attribute(primary_key) + if result.size == ids.size + pk_type = @klass.type_for_attribute(primary_key) - records_by_id = result.index_by(&:id) - ids.map { |id| records_by_id.fetch(pk_type.cast(id)) } - else - raise_record_not_found_exception!(ids, result.size, ids.size) + records_by_id = result.index_by(&:id) + ids.map { |id| records_by_id.fetch(pk_type.cast(id)) } + else + raise_record_not_found_exception!(ids, result.size, ids.size) + end end - end - def find_take - if loaded? - records.first - else - @take ||= limit(1).records.first + def find_take + if loaded? + records.first + else + @take ||= limit(1).records.first + end end - end - def find_take_with_limit(limit) - if loaded? - records.take(limit) - else - limit(limit).to_a + def find_take_with_limit(limit) + if loaded? + records.take(limit) + else + limit(limit).to_a + end end - end - def find_nth(index) - @offsets[offset_index + index] ||= find_nth_with_limit(index, 1).first - end + def find_nth(index) + @offsets[offset_index + index] ||= find_nth_with_limit(index, 1).first + end - def find_nth_with_limit(index, limit) - if loaded? - records[index, limit] || [] - else - relation = if order_values.empty? && primary_key - order(arel_attribute(primary_key).asc) + def find_nth_with_limit(index, limit) + if loaded? + records[index, limit] || [] else - self + relation = if order_values.empty? && primary_key + order(arel_attribute(primary_key).asc) + else + self + end + + relation = relation.offset(offset_index + index) unless index.zero? + relation.limit(limit).to_a end - - relation = relation.offset(offset_index + index) unless index.zero? - relation.limit(limit).to_a end - end - def find_nth_from_last(index) - if loaded? - records[-index] - else - relation = if order_values.empty? && primary_key - order(arel_attribute(primary_key).asc) + def find_nth_from_last(index) + if loaded? + records[-index] else - self + relation = if order_values.empty? && primary_key + order(arel_attribute(primary_key).asc) + else + self + end + + relation.to_a[-index] + # TODO: can be made more performant on large result sets by + # for instance, last(index)[-index] (which would require + # refactoring the last(n) finder method to make test suite pass), + # or by using a combination of reverse_order, limit, and offset, + # e.g., reverse_order.offset(index-1).first end - - relation.to_a[-index] - # TODO: can be made more performant on large result sets by - # for instance, last(index)[-index] (which would require - # refactoring the last(n) finder method to make test suite pass), - # or by using a combination of reverse_order, limit, and offset, - # e.g., reverse_order.offset(index-1).first end - end - - private - def find_last(limit) - limit ? records.last(limit) : records.last - end + def find_last(limit) + limit ? records.last(limit) : records.last + end end end |