jrochkind / attr_json

Serialized json-hash-backed ActiveRecord attributes, super smooth

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

some support for partial jsonb update using postgres jsonb update operators

jrochkind opened this issue · comments

I've looked before at hooking into standard ActiveRecord API to make it happen automatially, but determined that was infeasible, ActiveRecord didn't seem to offer appropriate hooks to override/customize how UPDATE statements are generated.

But we could still potentially do it with our own API, you wouldn't get it on AR save, but could call special jsonb methods of some sort.

Note a lot of work that @volkanunsal did some years back at #65

@volkanunsal, I am curious if you are still using this gem, and what's up!

Sorry for being discouraging before, it seemed like a big feature that I was cautious to get right... but I'm still thinking about it!

This would be amazing - subscribing to the thread in case any updates happen

@doutatsu I haven't figured out any way to do it that doesn't monkey-patch ActiveRecord so hard it makes me worry about maintainability.

It might ideally take some new API to ActiveRecord, which I'm not sure we'd have any chance of getting merged, so haven't spent the time to work out what it might be.

But if anyone else wants to experiment and let us know what they have figured out, it is of course welcome! I am reluctant to merge anything that monkey-patches AR beyond in a very trivial way though.

I agree it would take the JSON in ActiveRecord approach to a whole new level!

It's not a must-have for sure, so happy to keep waiting till it will be possible. I am using my own custom logic to deep merge the configuration in some places, so it's working fine, but hopefully it will be possible to make it simple in the future

I (and maybe others) am curious to learn more about the approach you are using for custom logic, if you'd like to share!

Imagining it, I'm not sure it's actually about the issue in this issue, but I'm not sure!

Ah it's nothing fancy at all - for my usecase, I just needed to set some custom overrides for specific fields, after the default has been set. So it's just doing some deep merging - and as I just started using this library, I am still honestly building a mental model on the most elegant way to set defaults and then override them in some cases

  desc 'Set default configuration for Source Sites'
  task set_default_configuration: :environment do
    sites = SourceSite.all
    configurations = YAML.load_file(
      Rails.root.join('lib/data/source_site_configuration.yml')
    )

    sites.find_each do |site|
      configuration = configurations[site.klass.underscore]

      attributes =
        if configuration
          config = Marshal.load(Marshal.dump(configurations['default']))

          configuration.each do |key, values|
            config[key] = config[key].to_h.deep_merge(values)
          end

          config
        else
          configurations['default']
        end

      site.update!(configuration: attributes)
    end
  end

In terms of this particular issue, it's more so avoiding doing something like this, which I have to do, instead of doing a single line of some sort to update one of the nested fields:

      site_headers = source_site.configuration.faraday.headers
      source_site.configuration.faraday.headers =
        site_headers.to_h.merge(authorization: headers['Authorization'])

      source_site.save!