Thanks Jeremy. I looked at something like that initially. It felt odd so I 
thought I'd check in for some other ideas, but I think the approach makes 
sense now that I've had time to get used to it :)


Meanwhile, I'm running into a new issue with associations changing in the 
after_save hook.

I started with code that looked like this:

I have a class Job with versions associated like so:

Job.one_to_many :versions, :class => 'JobVersion', :order => :created_at

And the after_save hook is like this:
    def after_save
      super
      version = JobVersion.new

      version.set @_version_meta.to_h if @_version_meta
      version.model = to_hash.except(:id,:created_at,:updated_at)
      version.diff = Hash.diff(version.model,versions.last.model) if 
versions.last
      add_version(version)
      @version_meta = nil
    end

Here the `JobVersion` columns `model` and `diff` are jsonb hashes. However 
I get the following:

Sequel::Error:         Sequel::Error: can't express #<JobVersion 
@values={:id=>134, :job_id=>15174, :user_id=>nil, :created_at=>2015-05-04 
10:37:46 -0400, :customer_note=>nil, :internal_note=>nil, :diff=>nil, 
:model=>{"state"=>"assigned", "credit"=>0.0, "net_price"=>50.0, 
"vendor_ap"=>42.5, "gross_price"=>50.0, "transaction_fee"=>1.75}}> as a SQL 
literal

I'm wondering if the jsonb columns are throwing this off? If I reconstruct 
the method like so:

    def after_save
      super
      version = JobVersion.new
      version.set @_version_meta.to_h if @_version_meta
      version.job_id = id
      version.model = to_hash.except(:id,:created_at,:updated_at)
      version.diff = Hash.diff(version.model,versions.last.model) if 
versions.last
      version.save
      @version_meta = nil
    end

Then it works, but the model has to be reloaded for the model.versions to 
be up to date.

Is there a way to tell the model to just reload the associations? Or do you 
know why the `add_version` call is failing?

Thanks!
Andrew


On Sunday, May 3, 2015 at 6:02:58 PM UTC-4, Andrew Burleson wrote:
>
> I'm working on doing some versioning on a sequel model. It's simple enough 
> to do something like: `Model.one_to_many :versions` and then use an 
> `after_save` hook to create a version which serializes the state of the 
> model.
>
> However, I'm interested in adding some optional field on the version 
> table, like user (who made the changes) and notes (why the changes were 
> made). I'd love to create a simple syntax for accessing these fields that 
> exist on the version table and not the original model, something like:
>
> a_model.update({name: "foo", amount: 123}) do |version|
>   version.user = current_user
>   version.note = "Updated model amount for some reason"
> end
>
> In the example above the idea is the model version will be created 
> regardless, but if a block is given the not yet saved version is yielded to 
> the block so the caller can access it (to add change notes etc).
>
> I've been able to make something like this work by overriding `save` and 
> `update`, but it's not dry, and it doesn't seem like this would cover all 
> the ways you can save a model (e.g. `update_all`). Meanwhile doing this via 
> a hook doesn't seem viable as I see no way to forward the optional block 
> from the various save-triggering methods.
>
> Any suggestions? Is there a standardized or better approach to 
> implementing versioning using sequel?
>
> Thanks!
> Andrew
>

-- 
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.

Reply via email to