jsonb_accessor icon indicating copy to clipboard operation
jsonb_accessor copied to clipboard

Prefix / Suffix feature

Open mmarusyk opened this issue 1 year ago • 4 comments

This PR introduces an improvement for utilizing prefix and suffix options for attribute names in jsonb_accessor.

Why?

In some cases, it suffices to store certain information about orders in jsonb format when it's only needed for historical purposes or for generating invoices, etc.

Results

How it currently looks in the Order model:

class Order < ApplicationRecord
  jsonb_accessor :contact_details,
                 contact_details_email: [:string, { store_key: :email }],
                 contact_details_last_name: [:string, { store_key: :last_name }],
                 contact_details_first_name: [:string, { store_key: :first_name }],
                 contact_details_phone_number: [:string, { store_key: :phone_number }]

  jsonb_accessor :billing_details,
                 billing_details_email: [:string, { store_key: :email }],
                 billing_details_last_name: [:string, { store_key: :last_name }],
                 billing_details_first_name: [:string, { store_key: :first_name }],
                 billing_details_phone_number: [:string, { store_key: :phone_number }],
                 billing_details_full_address_line: [:string, { store_key: :full_address_line }]

  jsonb_accessor :shipping_details,
                 shipping_details_full_address_line: [:string, { store_key: :full_address_line }]
end

How it will look after implementing prefixes:

class Order < ApplicationRecord
  jsonb_accessor :contact_details,
                 email: [:string, { prefix: true }],
                 last_name: [:string, { prefix: true }],
                 first_name: [:string, { prefix: true }],
                 phone_number: [:string, { prefix: true }]

  jsonb_accessor :billing_details,
                 email: [:string, { prefix: true }],
                 last_name: [:string, { prefix: true }],
                 first_name: [:string, { prefix: true }],
                 phone_number: [:string, { prefix: true }],
                 full_address_line: [:string, { prefix: true }]

  jsonb_accessor :shipping_details,
                 full_address_line: [:string, { prefix: true }]
end

In rails console:

order.billing_details #=> {"email"=>"[email protected]", "last_name"=>"Mosciski", "first_name"=>"Chi", "phone_number"=>"475912955432", "full_address_line"=>"Suite 897 932 Nitzsche Shoal, Tammiborough, MI 90349-4217"}
order.billing_details_first_name #=> "Chi"
order.contact_details_first_name #=> "Marquita"
order.contact_details #=> {"email"=>"[email protected]", "last_name"=>"Wunsch", "first_name"=>"Marquita", "phone_number"=>"278587369859"}
order.update(contact_details_first_name: "Mike", billing_details_first_name: "John") #=> true
order.reload.billing_details #=> {"email"=>"[email protected]", "last_name"=>"Mosciski", "first_name"=>"John", "phone_number"=>"475912955432", "full_address_line"=>"Suite 897 932 Nitzsche Shoal, Tammiborough, MI 90349-4217"}
order.reload.contact_details #=> {"email"=>"[email protected]", "last_name"=>"Wunsch", "first_name"=>"Mike", "phone_number"=>"278587369859"}
order.contact_details_last_name="Marsk" #=> "Marsk"
order.contact_details_last_name #=> "Marsk"
order.contact_details #=> {"email"=>"[email protected]", "last_name"=>"Marsk", "first_name"=>"Mike", "phone_number"=>"278587369859"}
irb(main):012:0> order.save #=> true
irb(main):013:0> Order.contact_details_where(last_name: "Marsk") #=>
[#<Order:0x00007f7a0a85fc88
  id: 2,
  contact_details: {"email"=>"[email protected]", "last_name"=>"Marsk", "first_name"=>"Mike", "phone_number"=>"278587369859"},
  billing_details: {"email"=>"[email protected]", "last_name"=>"Mosciski", "first_name"=>"John", "phone_number"=>"475912955432", "full_address_line"=>"Suite 897 932 Nitzsche Shoal, Tammiborough, MI 90349-4217"},
  shipping_details: {"full_address_line"=>"38266 Durgan Motorway, Kulasmouth, NC 46602-3316"},
  contact_details_email: "[email protected]",
  contact_details_last_name: "Marsk",
  contact_details_first_name: "Mike",
  contact_details_phone_number: "278587369859",
  billing_details_email: "[email protected]",
  billing_details_last_name: "Mosciski",
  billing_details_first_name: "John",
  billing_details_phone_number: "475912955432",
  billing_details_full_address_line: "Suite 897 932 Nitzsche Shoal, Tammiborough, MI 90349-4217",
  shipping_details_full_address_line: "38266 Durgan Motorway, Kulasmouth, NC 46602-3316">]
irb(main):014:0> Order.contact_details_where(last_name: "Random") #=> []

Also, it works fine with store key:

class Order < ApplicationRecord
  jsonb_accessor :contact_details,
                 email: [:string, { prefix: true, store_key: :e }], # Added store key
                 last_name: [:string, { prefix: true }],
                 first_name: [:string, { prefix: true }],
                 phone_number: [:string, { prefix: true }]

  jsonb_accessor :billing_details,
                 email: [:string, { prefix: true }],
                 last_name: [:string, { prefix: true }],
                 first_name: [:string, { prefix: true }],
                 phone_number: [:string, { prefix: true }],
                 full_address_line: [:string, { prefix: true }]

  jsonb_accessor :shipping_details,
                 full_address_line: [:string, { prefix: true }]
end
order.contact_details #=> {"e"=>"[email protected]", "last_name"=>"Kshlerin", "first_name"=>"Jessie", "phone_number"=>"567805903539"}
irb(main):021:0> order.contact_details_email="[email protected]" #=> "[email protected]"
order.contact_details_email #=> "[email protected]"
order.contact_details #=> {"e"=>"[email protected]", "last_name"=>"Kshlerin", "first_name"=>"Jessie", "phone_number"=>"567805903539"}
order.save #=> true
order.reload.contact_details #=> {"e"=>"[email protected]", "last_name"=>"Kshlerin", "first_name"=>"Jessie", "phone_number"=>"567805903539"}

For quering you can use name attribute without prefix/suffix:

Order.find(7).contact_details => {"e"=>"[email protected]"}
Order.contact_details_where(email: "[email protected]") # =>
[#<Order:0x00007f96bdd7a158
  id: 7,
  contact_details: {"e"=>"[email protected]"},
  billing_details: nil,
  shipping_details: nil,
  created_at: Sun, 07 Apr 2024 11:15:37.782726000 UTC +00:00,
  updated_at: Sun, 07 Apr 2024 11:15:37.782726000 UTC +00:00,
  contact_details_email: "[email protected]",
  contact_details_last_name: nil,
  contact_details_first_name: nil,
  contact_details_phone_number: nil,
  billing_details_email: nil,
  billing_details_last_name: nil,
  billing_details_first_name: nil,
  billing_details_phone_number: nil,
  billing_details_full_address_line: nil,
  shipping_details_full_address_line: nil>]

I'll be happy if we have this improvement in this gem. Thank you!

#173

mmarusyk avatar Apr 07 '24 09:04 mmarusyk

Wow, thanks @mmarusyk for this contribution. I think it's super helpful.

haffla avatar Apr 08 '24 04:04 haffla

This is great <3 we're using this a while now and it works perfectly fine :)

If I'll find the time I'd like to try and implement a top level setting like this:

jsonb_accessor :contact_details,
                 email: :string,
                 last_name: :string,
                 first_name: :string,
                 phone_number: :string,
                 { prefix: true }

nduitz avatar Jul 25 '24 15:07 nduitz

Wait, this was never merged?

haffla avatar Jul 25 '24 16:07 haffla

Well apparently I have just been removed as contributor.

haffla avatar Aug 06 '24 15:08 haffla

Hi! Is this PR planned to be merged?

Also, I’d appreciate any updates on whether the gem is still actively supported and open to contributions.

mmarusyk avatar Nov 21 '24 16:11 mmarusyk

@haffla do you know who has access to this repository and/or the Rubygem?

ashkulz avatar Mar 18 '25 04:03 ashkulz

Hi @ashkulz. No not really. I had contacted the CEO of madeintandem in the past. His last answer was in Nov 2024. He asked for my Github username which I gave him. Since then nothing... I personally don't use this gem anymore.

haffla avatar Mar 18 '25 06:03 haffla

@thegrubbsian / @SteveSchneider, do you know who has access to the repo and/or RubyGem? I'm willing to step up as maintainer as I actively use this at work. I'm also the maintainer for pronto and have contributed to this gem before (#157, #164).

ashkulz avatar Mar 18 '25 11:03 ashkulz

We are also using this in GitLab and I think this is really helpful, since we also have multiple jsonb columns in our ApplicationSetting model.

lulalala avatar Apr 01 '25 08:04 lulalala

Hello, I just got maintainer access to this repo (thanks @darcygarrett!) so I should be able to review this after I do some housekeeping. @mmarusyk would you be willing to rebase and reopen this PR?

ashkulz avatar Apr 25 '25 06:04 ashkulz

@ashkulz Hello, I've created a new pull request since it's not possible to reopen this one.

mmarusyk avatar May 06 '25 18:05 mmarusyk