Provide pattern matching for ActiveModel
It would be nice to be able to pattern match against ActiveModel (and transitively ActiveRecord). If you want to check multiple attributes with conditions, it's nice to be able use the pattern matching syntax. For example: ```ruby case Current.user in { superuser: true } "Thanks for logging in. You are a superuser." in { admin: true, name: } "Thanks for logging in, admin #{name}!" in { name: } "Welcome, #{name}!" end ```
This commit is contained in:
parent
e1a9b3d861
commit
7e499b25ac
|
@ -1,3 +1,21 @@
|
|||
* Define `deconstruct_keys` in `ActiveModel::AttributeMethods`
|
||||
|
||||
This provides the Ruby 2.7+ pattern matching interface for hash patterns,
|
||||
which allows the user to pattern match against anything that includes the
|
||||
`ActiveModel::AttributeMethods` module (e.g., `ActiveRecord::Base`). As an
|
||||
example, you can now:
|
||||
|
||||
```ruby
|
||||
class Person < ActiveRecord::Base
|
||||
end
|
||||
|
||||
person = Person.new(name: "Mary")
|
||||
person => { name: }
|
||||
name # => "Mary"
|
||||
```
|
||||
|
||||
*Kevin Newton*
|
||||
|
||||
* Fix casting long strings to `Date`, `Time` or `DateTime`
|
||||
|
||||
*fatkodima*
|
||||
|
|
|
@ -489,6 +489,43 @@ module ActiveModel
|
|||
end
|
||||
end
|
||||
|
||||
# Returns a hash of attributes for the given keys. Provides the pattern
|
||||
# matching interface for matching against hash patterns. For example:
|
||||
#
|
||||
# class Person
|
||||
# include ActiveModel::AttributeMethods
|
||||
#
|
||||
# attr_accessor :name
|
||||
# define_attribute_method :name
|
||||
# end
|
||||
#
|
||||
# def greeting_for(person)
|
||||
# case person
|
||||
# in { name: "Mary" }
|
||||
# "Welcome back, Mary!"
|
||||
# in { name: }
|
||||
# "Welcome, stranger!"
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# person = Person.new
|
||||
# person.name = "Mary"
|
||||
# greeting_for(person) # => "Welcome back, Mary!"
|
||||
#
|
||||
# person = Person.new
|
||||
# person.name = "Bob"
|
||||
# greeting_for(person) # => "Welcome, stranger!"
|
||||
def deconstruct_keys(keys)
|
||||
deconstructed = {}
|
||||
|
||||
keys.each do |key|
|
||||
string_key = key.to_s
|
||||
deconstructed[key] = _read_attribute(string_key) if attribute_method?(string_key)
|
||||
end
|
||||
|
||||
deconstructed
|
||||
end
|
||||
|
||||
private
|
||||
def attribute_method?(attr_name)
|
||||
respond_to_without_attributes?(:attributes) && attributes.include?(attr_name)
|
||||
|
|
|
@ -175,5 +175,14 @@ module ActiveModel
|
|||
ModelForAttributesTest.attribute :foo, :unknown
|
||||
end
|
||||
end
|
||||
|
||||
test "pattern matching against keys" do
|
||||
case ModelForAttributesTest.new(integer_field: 1)
|
||||
in { integer_field: 1 }
|
||||
assert(true)
|
||||
else
|
||||
assert(false, "Failed to pattern match")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue