Skip to content

Commit 0654a61

Browse files
ghiculescujhawthorn
andcommitted
Ensure consistent sort order in ActiveModel#serializable_hash when using only option
This is a bit of a nitpick, but say you do this: ```ruby user.as_json(only: [:email, :name]).keys ``` The result will depend on the order that the columns were added to your database (or in a test environment, the order of the columns in your `structure.sql`). ie. you might get `["email", "name"]` or `["name", "email"]`. In the specific case that you've provided `only` you are being explicit about which fields should be returned, so we can also be explicit about the order that they are returned in. This PR implements that. Now it will always return fields based on the order they're provided to the `only` argument, so in this case it would always be `["email", "name"]`. Co-authored-by: John Hawthorn <[email protected]>
1 parent 88dc93e commit 0654a61

File tree

2 files changed

+6
-1
lines changed

2 files changed

+6
-1
lines changed

activemodel/lib/active_model/serialization.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ def serializable_hash(options = nil)
128128
return serializable_attributes(attribute_names) if options.blank?
129129

130130
if only = options[:only]
131-
attribute_names &= Array(only).map(&:to_s)
131+
attribute_names = Array(only).map(&:to_s) & attribute_names
132132
elsif except = options[:except]
133133
attribute_names -= Array(except).map(&:to_s)
134134
end

activemodel/test/cases/serialization_test.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ def test_method_serializable_hash_should_work_with_only_option
6262
assert_equal expected, @user.serializable_hash(only: [:name])
6363
end
6464

65+
def test_method_serializable_hash_should_work_with_only_option_with_order_of_given_keys
66+
expected = { "name" => "David", "email" => "[email protected]" }
67+
assert_equal expected.keys, @user.serializable_hash(only: [:name, :email]).keys
68+
end
69+
6570
def test_method_serializable_hash_should_work_with_except_option
6671
expected = { "gender" => "male", "email" => "[email protected]" }
6772
assert_equal expected, @user.serializable_hash(except: [:name])

0 commit comments

Comments
 (0)