Reputation: 1783
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?
Upvotes: 15
Views: 8748
Reputation: 8402
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)
Upvotes: 12
Reputation: 1235
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.
Upvotes: 9