How to edit a Rails serialized field in a form?

后端 未结 8 642
-上瘾入骨i
-上瘾入骨i 2020-12-04 07:16

I have a data model in my Rails project that has a serialized field:

class Widget < ActiveRecord::Base
  serialize :options
end

The opti

相关标签:
8条回答
  • 2020-12-04 08:11

    Well, I had the same problem, and tried not to over-engineer it. The problem is, that although you can pass the serialized hash to fields_for, the fields for function will think, it is an option hash (and not your object), and set the form object to nil. This means, that although you can edit the values, they will not appear after editing. It might be a bug or unexpected behavior of rails and maybe fixed in the future.

    However, for now, it is quite easy to get it working (though it took me the whole morning to figure out).

    You can leave you model as is and in the view you need to give fields for the object as an open struct. That will properly set the record object (so f2.object will return your options) and secondly it lets the text_field builder access the value from your object/params.

    Since I included " || {}", it will work with new/create forms, too.

    = form_for @widget do |f|
      = f.fields_for :options, OpenStruct.new(f.object.options || {}) do |f2|
        = f2.text_field :axis_y
        = f2.text_field :axis_x
        = f2.text_field :unit
    

    Have a great day

    0 讨论(0)
  • 2020-12-04 08:11

    I was facing the same issue, after some research i found a solution using Rails' store_accessor to make keys of a serialized column accessible as attributes.

    With this we can access "nested" attributes of a serialized column …

    # post.rb
    class Post < ApplicationRecord
      serialize :options
      store_accessor :options, :value1, :value2, :value3
    end
    
    # set / get values
    post = Post.new
    post.value1 = "foo"
    post.value1
    #=> "foo"
    post.options['value1']
    #=> "foo"
    
    # strong parameters in posts_controller.rb
    params.require(:post).permit(:value1, :value2, :value3)
    
    # form.html.erb
    <%= form_with model: @post, local: true do |f| %>
      <%= f.label :value1 %>
      <%= f.text_field :value1 %>
      # …
    <% end %>
    
    0 讨论(0)
提交回复
热议问题