medBouzid
medBouzid

Reputation: 8402

Is it possible to show a form with fields for the jsonb properties

I have a Product model with a jsonb field called dynamic.

I have actually 2 product records

Product 1 :

dynamic = {"name": "super product 1", "description": "lorem ipsum text" }

Product 2 :

dynamic = {"title": "this is an ebook", "author": "john doe", "creation_date": "2015"}

To edit each product I need to show a form. for the product 1 the form will contains 2 fields (name and description), and for product 2 the form will contains 3 fields (title, author,creation_date)

I have searched but it seem that all the articles I have found talk about how to use the console to save or edit a json field but no one talks about how to use the form.

any help please ? Thanks

Upvotes: 6

Views: 3149

Answers (2)

Miguel Peniche
Miguel Peniche

Reputation: 1032

Hey @IngoAlbers I am using your approach in my forms and is working great, I just have a couple of inquiries that may add some features. Having this form:

<%= simple_form_for @user: :update do |form| %>
  <%= form.input :phone %>
  <%= form.simple_fields_for :group do |field| %>
    <%= field.input :name %>
  <% end %>
  <%= form.submit, "Update" %>
<% end %>

How can I let the input show an error on that specific field when validating?. I mean it is making the validation and not letting the method to continue but is not showing it in the field when rendering the page. The code and results:

errors.add :phone, :blank if phone.blank?
errors.add "group.name", :blank if group["name"].blank?

I've tried with :"group.name", :group_name and some other similar stuff without success, the other association and attributes fields like :phone work just fine.


#<ActiveModel::Error attribute=phone, type=blank, options={}>,
#<ActiveModel::Error attribute=group_name, type=blank, options={}>,

And just for fun, it would be great if there's a way to use translations as labels in fields_for. For example:

es:
  activerecord:
    attributes:
      user:
        phone: Teléfono móvil
        group:
          name: Grupo

I have also tried with group.name, group_name and nothing, here is the result of everything:

enter image description here

I know there's a way to do it, hope you can help me.

Upvotes: 0

IngoAlbers
IngoAlbers

Reputation: 5802

If you are using simple_form you can do something like this:

f.simple_fields_for :dynamic do |dynamic_f|
  @product.dynamic.each do |k,v|
    dynamic_f.input k.to_sym
  end
end

Don't forget to allow the parameters in the controller like this:

params.require(:product).permit(dynamic: [:name, :description, :title, :author, :creation_date]])

It is always good practice to whitelist the specific params that you need but if you want to allow everything inside dynamic you can try something like this:

params.require(:product)permit( **permitted paramters in here** ).tap do |whitelisted|
  whitelisted[:dynamic] = params[:product][:dynamic] if params[:product][:dynamic]
end

Or to allow everything for the product model use:

params.require(:product).permit!

This is not recommended though as it would leave your other data outside of the json field open to be overwritten.

Upvotes: 6

Related Questions