15

I'm looking at using the new jsonb capability in Rails4.2 and Postgres4.1.

I was looking at creating a model which represents a user profile (i.e. skill sets, etc) and storing the whole thing in a single jsonb dataset.

So the table would have:

id int
profile jsonb
timestamps

I was thinking I could basically store all the profile data in the jsonb structure as follows (this is just an example/concept):

{
  "basics": {
    "name": "John Doe",
    "label": "Programmer",
    "picture": "",
    "email": "[email protected]",
    "phone": "(912) 555-4321",
    "website": "http://johndoe.com",
    "summary": "A summary of John Doe...",
    "location": {
      "address": "2712 Broadway St",
      "postalCode": "CA 94115",
      "city": "San Francisco",
      "countryCode": "US",
      "region": "California"
    },
    "profiles": [{
      "network": "Twitter",
      "username": "john",
      "url": "http://twitter.com/john"
    }]
  },
"skills": [{
    "name": "Web Development",
    "level": "Master",
    "keywords": [
      "HTML",
      "CSS",
      "Javascript"
    ]
  }],
  "languages": [{
    "language": "English",
    "fluency": "Native speaker"
  }],
}

My question is how would I create a basic rails form that would write/read to this structure? I understand how to do it to a traditional relational set of tables, but not sure how to approach when it could all go into a flexible structure like the below?

What would happen at the _form.html.erb and in the controller new/create/edit actions?

1
  • I am in the same situation. Have you found any solution ? Commented Apr 5, 2015 at 0:54

2 Answers 2

12

I don't know about the previous versions but in Rails 6 from the doc: https://api.rubyonrails.org/classes/ActiveRecord/Store.html

you can use store like this:

class MyModel < ApplicationRecord
    store :my_jsonb_field_name, accessors: [:property1, :property2]
end

Now if you have a form with <%= form.text_field :property1 %> and <%= form.text_field :property2 %> they will be automatically mapped to your json/jsonb field and you will be able to treat them like if they were a regular (varchar/string) fields.

Do Not forget to permit :property1 and property2 etc in your strong parameters, i.e:

params.require(:my_model).permit(:title, [...], :property1, :property2)
Sign up to request clarification or add additional context in comments.

Comments

9

Use store_accessors. Form data is just a Hash, that could be easily converted to a JSON object and persisted in postgresql without major problems.

Assuming your form submits all profile data in a profile[] hash and your models look something like this:

class User < ActiveRecord::Base
  has_one :profile
end

class Profile < ActiveRecord::Base
  belongs_to :user
  store_accessor :profile
end

You could simply do something like:

user.profile = params[:profile]
user.profile.save

In your controller (or anywhere else) and it should work.

2 Comments

awesome! any downsides or gotchas to watch out for?
@cman77 Rails is doing a lot of serializing/deserializing for you without you knowing. As usual with Rails, when it works it looks like magic, but might cause some trouble. Watch out for non-conventional data structures. Everything that can be safely serialized into JSON should work fine, though.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.