Added Hashie::Extensions::Mash::ActiveModel for compatibility with Rails 4 Strong Parameters.
This commit is contained in:
parent
3cdd44af36
commit
5ac85162db
|
@ -1,6 +1,7 @@
|
|||
## Next
|
||||
|
||||
* Your contribution here.
|
||||
* [#146](https://github.com/intridea/hashie/issues/146): Mash#respond_to? inconsistent with #method_missing and does not respond to #permitted? - [@dblock](https://github.com/dblock).
|
||||
* [#89](https://github.com/intridea/hashie/issues/89): Added Hashie::Extensions::Mash::ActiveModel for compatibility with Rails 4.x Strong Parameters - [@dblock](https://github.com/dblock).
|
||||
|
||||
## 2.1.1 (4/12/2014)
|
||||
|
||||
|
|
10
README.md
10
README.md
|
@ -238,6 +238,16 @@ p[:awesome] # => NoMethodError
|
|||
p[:occupation] # => 'Rubyist'
|
||||
```
|
||||
|
||||
### Mash and Rails 4 Strong Parameters
|
||||
|
||||
Add the following initializer in config/initializers/mash.rb when using Mash with [Rails 4 Strong Parameters](http://edgeguides.rubyonrails.org/action_controller_overview.html#strong-parameters). This prevents Mash from responding to `:permitted?` and therefore triggering an ActiveModel `ForbiddenAttributesProtection` exception.
|
||||
|
||||
```ruby
|
||||
class Mash
|
||||
include Hashie::Extensions::Mash::ActiveModel
|
||||
end
|
||||
```
|
||||
|
||||
## Trash
|
||||
|
||||
A Trash is a Dash that allows you to translate keys on initialization.
|
||||
|
|
|
@ -22,5 +22,9 @@ module Hashie
|
|||
autoload :StringifyKeys, 'hashie/extensions/key_conversion'
|
||||
autoload :SymbolizeKeys, 'hashie/extensions/key_conversion'
|
||||
autoload :DeepFetch, 'hashie/extensions/deep_fetch'
|
||||
|
||||
module Mash
|
||||
autoload :ActiveModel, 'hashie/extensions/mash/active_model'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
module Hashie
|
||||
module Extensions
|
||||
module Mash
|
||||
# Extends Mash to behave in a way compatible with ActiveModel.
|
||||
module ActiveModel
|
||||
def respond_to?(name, include_private = false)
|
||||
return false if name == :permitted?
|
||||
super
|
||||
end
|
||||
|
||||
def method_missing(name, *args)
|
||||
fail ArgumentError if name == :permitted?
|
||||
super
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -57,6 +57,7 @@ module Hashie
|
|||
class Mash < Hash
|
||||
ALLOWED_SUFFIXES = %w(? ! = _)
|
||||
include Hashie::PrettyInspect
|
||||
|
||||
alias_method :to_s, :inspect
|
||||
|
||||
# If you pass in an existing hash, it will
|
||||
|
@ -185,11 +186,15 @@ module Hashie
|
|||
self
|
||||
end
|
||||
|
||||
# Will return true if the Mash has had a key
|
||||
# set in addition to normal respond_to? functionality.
|
||||
def respond_to?(method_name, include_private = false)
|
||||
return true if key?(method_name) || prefix_method?(method_name)
|
||||
super
|
||||
return true if key?(method_name)
|
||||
_, suffix = method_suffix(method_name)
|
||||
case suffix
|
||||
when '=', '?', '!', '_'
|
||||
return true
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
def prefix_method?(method_name)
|
||||
|
@ -199,17 +204,16 @@ module Hashie
|
|||
|
||||
def method_missing(method_name, *args, &blk)
|
||||
return self.[](method_name, &blk) if key?(method_name)
|
||||
suffixes_regex = ALLOWED_SUFFIXES.join
|
||||
match = method_name.to_s.match(/(.*?)([#{suffixes_regex}]?)$/)
|
||||
case match[2]
|
||||
name, suffix = method_suffix(method_name)
|
||||
case suffix
|
||||
when '='
|
||||
self[match[1]] = args.first
|
||||
self[name] = args.first
|
||||
when '?'
|
||||
!!self[match[1]]
|
||||
!!self[name]
|
||||
when '!'
|
||||
initializing_reader(match[1])
|
||||
initializing_reader(name)
|
||||
when '_'
|
||||
underbang_reader(match[1])
|
||||
underbang_reader(name)
|
||||
else
|
||||
default(method_name)
|
||||
end
|
||||
|
@ -217,6 +221,12 @@ module Hashie
|
|||
|
||||
protected
|
||||
|
||||
def method_suffix(method_name)
|
||||
suffixes_regex = ALLOWED_SUFFIXES.join
|
||||
match = method_name.to_s.match(/(.*?)([#{suffixes_regex}]?)$/)
|
||||
[match[1], match[2]]
|
||||
end
|
||||
|
||||
def convert_key(key) #:nodoc:
|
||||
key.to_s
|
||||
end
|
||||
|
|
|
@ -328,9 +328,9 @@ describe Hashie::Mash do
|
|||
end
|
||||
end
|
||||
|
||||
it 'does not respond to an unknown key with a suffix' do
|
||||
it 'responds to an unknown key with a suffix' do
|
||||
%w(= ? ! _).each do |suffix|
|
||||
expect(Hashie::Mash.new(abc: 'def')).not_to be_respond_to(:"xyz#{suffix}")
|
||||
expect(Hashie::Mash.new(abc: 'def')).to be_respond_to(:"xyz#{suffix}")
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -339,7 +339,12 @@ describe Hashie::Mash do
|
|||
end
|
||||
|
||||
it 'does not respond to permitted?' do
|
||||
expect(Hashie::Mash.new).not_to be_respond_to(:permitted?)
|
||||
expect(Hashie::Mash.new).to be_respond_to(:permitted?)
|
||||
klass = Class.new(Hashie::Mash) do
|
||||
include Hashie::Extensions::Mash::ActiveModel
|
||||
end
|
||||
expect(klass.new).not_to be_respond_to(:permitted?)
|
||||
expect { klass.new.permitted? }.to raise_error(ArgumentError)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue