On Monday, September 22, 2014 12:05:15 PM UTC-7, [email protected]
wrote:
>
> Hello!
>
> I was using Sequel 4.12.0 in my Rails app and after upgrading to 4.14.0,
> suddenly things broke and models stopped saving the serialized data in the
> corresponding columns.
>
> After navigating a lot through the Sequel repo, I found the problem
> started when the serialize_deserialized_values method was put inside the
> _before_validation hook instead of in before_save in this commit
> <https://github.com/jeremyevans/sequel/commit/c61a63994a267175fbeff6f0231634c7510c3229>.
>
> This was done to allow validation of the serialization columns, for what I
> can read.
>
> I used the Serialization plugin to do what ActiveRecord::Store does using
> virtual attributes. Here's an example:
>
> class Example
> plugin :serialization, :json, :data
>
> attr_accessor :attr1, :attr2
>
> def validate
> validates_presence [:attr1, :attr2]
> end
>
> def after_validation
> # The next method takes attr1, and attr2 and stores them inside their
> corresponding keys inside the "data" Hash
> put_attributes_into_data
> end
> end
>
> That way, I was sure underlying attributes would get validated before they
> got into the "data" Hash and serialized by the Serialization plugin, just
> like AR::Store does.
>
> In the new version I could no longer do this because the Serialization
> Plugin tried to serialize the attributes before they even got to the hash
> in the @deserialized_values variable. The only thing I could do was to put
> the attributes inside the Hash before validation (calling
> "put_attributes_into_data" inside _before_validation), so that they'd get
> serialized and then validated, which is not pretty, especially if you
> happen to have a lot to serialize (not my case yet, fortunately).
>
> My question is: is there a way to achieve the same thing I had before
> (where things got validated and then serialized if everything went good) in
> the new version that I missed?
>
> Maybe I even got too far by doing the virtual attributes thing and there's
> a more sophisticated way to achive ActiveRecord::Store-like functionality.
>
Sorry about that. You fix a bug and end up breaking things for people
relying on the bug. :)
This is a catch 22, as you can't serialize the column both before
validation and after validation. So the only thing I can really do to
accommodate your use case this is to add an option for the previous
behavior, where it runs in before_save instead of _before_validation. I'll
consider that, but please keep reading.
Sequel doesn't currently have a plugin for ActiveRecord::Store like
functionality. Personally, I think it's just a bad idea. If you are using
PostgreSQL, my recommendation would be to use a native json column with
Sequel's pg_json extension, and instead of using attr_accessor, just add
instance methods that get/set the value in the json hash:
class Example < Sequel::Model
def attr1
data['attr1']
end
def attr1=(v)
modified!(:data)
data['attr1'] = v
end
def attr2
data['attr2']
end
def attr2=(v)
modified!(:data)
data['attr2'] = v
end
def validate
validates_presence [:attr1, :attr2]
end
end
With that approach, you don't need to use the serialization plugin or have
an after_validation hook, and things should just work.
If you still want me to add an option to the serialization plugin that
reverts to the previous behavior, please let me know.
Thanks for the report,
Jeremy
--
You received this message because you are subscribed to the Google Groups
"sequel-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sequel-talk.
For more options, visit https://groups.google.com/d/optout.