From 458fff60ce78723ec904bd1085b4bc9d89a0574f Mon Sep 17 00:00:00 2001 From: Guillaume Briday Date: Mon, 29 Jul 2019 00:49:31 +0200 Subject: [PATCH] Add values_at attribute method for active_record --- activerecord/CHANGELOG.md | 14 ++++++++++++++ activerecord/lib/active_record/core.rb | 5 +++++ activerecord/test/cases/base_test.rb | 15 +++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index af82919268..9bdab1786e 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,17 @@ +* Add `values_at` method. + + Returns an array containing the values associated with the given methods. + + ```ruby + topic = Topic.first + topic.values_at(:title, :author_name) + # => ["Budget", "Jason"] + ``` + + Similar to `Hash#values_at` but on an Active Record instance. + + *Guillaume Briday* + * Fix `read_attribute_before_type_cast` to consider attribute aliases. *Marcelo Lauxen* diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb index 83d1b786b6..054f26a516 100644 --- a/activerecord/lib/active_record/core.rb +++ b/activerecord/lib/active_record/core.rb @@ -601,6 +601,11 @@ module ActiveRecord Hash[methods.flatten.map! { |method| [method, public_send(method)] }].with_indifferent_access end + # Returns an array of the values returned by the given methods. + def values_at(*methods) + methods.flatten.map! { |method| public_send(method) } + end + private # +Array#flatten+ will call +#to_ary+ (recursively) on each of the elements of # the array, and then rescues from the possible +NoMethodError+. If those elements are diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index 30261f37d0..872f9a5778 100644 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -1411,6 +1411,21 @@ class BasicsTest < ActiveRecord::TestCase assert_equal attrs, topic.slice(attrs.keys) end + def test_values_at + company = Company.new(name: "37signals", rating: 1) + + assert_equal [ "37signals", 1, "I am Jack's profound disappointment" ], + company.values_at(:name, :rating, :arbitrary_method) + assert_equal [ "I am Jack's profound disappointment", 1, "37signals" ], + company.values_at(:arbitrary_method, :rating, :name) + end + + def test_values_at_accepts_array_argument + topic = Topic.new(title: "Budget", author_name: "Jason") + + assert_equal %w( Budget Jason ), topic.values_at(%w( title author_name )) + end + def test_default_values_are_deeply_dupped company = Company.new company.description << "foo"