Support AC::Parameters for PG HStore #27058

Merged
merged 1 commit into from Nov 15, 2016

Projects

None yet

3 participants

@maclover7
Member
maclover7 commented Nov 15, 2016 edited

Summary

  • changelog
  • regression test
  • make commit description more descriptive
@sgrif
Member
sgrif commented Nov 15, 2016

This is fine to merge once CI is green.

@sgrif
Member
sgrif commented Nov 15, 2016

Please add a test though. :)

@sgrif

to_unsafe_hash is the correct method to call.

@maclover7
Member

@sgrif are you sure we want the to_unsafe_hash / to_unsafe_h method being called? I'm just worried about unpermitted keys slipping through, and potential sec issues...

@sgrif
Member
sgrif commented Nov 15, 2016

Yes. It isn't a sec issue. to_unsafe_h mirrors the behavior of 4.2 and earlier.

@sgrif
Member
sgrif commented Nov 15, 2016

to_h will also have unintended consequences which is why we almost never use it as a solution to the "params no longer inherit from hash" problem

@maclover7
Member

updated @sgrif

@@ -10,6 +10,12 @@ class Hstore < ActiveRecord::Base
store_accessor :settings, :language, :timezone
end
+ class FakeParameters
+ def to_h
@sgrif
sgrif Nov 15, 2016 Member

This is wrong

@maclover7
maclover7 Nov 15, 2016 Member

derp, sorry, fixing now

@sgrif
sgrif Nov 15, 2016 Member

Once that's fixed this is fine to squash and merge. Don't forget to backport to 5-0-stable.

@maclover7 maclover7 Support AC::Parameters for PG HStore
As reported via #26904, there is a regression in how values for
Postgres' HStore column type are being processed, beginning in Rails 5.
Currently, the way that Active Record checks whether or not values need
to be serialized and put into the correct storage format is whether or
not it is a `Hash` object. Since `ActionController::Parameters` no
longer inherits from `Hash` in Rails 5, this conditional now returns
false. To remedy this, we are now checking to see whether the `value`
parameters being passed in responds to a certain method, and then
calling the `serialize` method, except this time with a real Hash
object. Keeping things DRY!

Fixes #26904.
0a8b212
@maclover7 maclover7 merged commit bce3d1f into rails:master Nov 15, 2016

2 checks passed

codeclimate Code Climate didn't find any new or fixed issues.
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
@maclover7 maclover7 deleted the maclover7:jm-fix-26904 branch Nov 15, 2016
@maclover7
Member

Backport PR: #27061

@@ -24,6 +24,8 @@ def deserialize(value)
def serialize(value)
if value.is_a?(::Hash)
value.map { |k, v| "#{escape_hstore(k)}=>#{escape_hstore(v)}" }.join(", ")
+ elsif value.respond_to?(:to_unsafe_h)
@kirs
kirs Nov 21, 2016 Contributor

Why do we allow unpermitted params to be persisted?
IMO, we should only persist params that have been permitted with strong parameters API.

@sgrif
sgrif Nov 22, 2016 Member

Because this is fundamentally different than attribute assignment elsewhere. It's assigning a value to a single known attribute. Similarly to how we don't require users to whitelist possible values for a string when assigning to a string column. Most importantly, this is matching the behavior of 4.2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment