使用 Rails 和 Postgresql 在 jsonb 字段中存储数组数据
Storing array data in jsonb field with Rails and Postgresql
假设我有一个汽车模型,我想在其中显示不同类型的数据。我将 data
列添加到 table:
class AddDataToCars < ActiveRecord::Migration[5.0]
def change
add_column :cars, :data, :jsonb, null: false, default: '{}'
add_index :cars, :data, using: :gin
end
end
然后我为我想要出现的字段添加一个访问器 (extra_options
):
class Car < ApplicationRecord
store_accessor :data, :wheel_count, :extra_options
validates :extra_options, presence: true
end
我确保它是 cars_controller.rb
中允许的参数:
def car_params
params.require(:car).permit(:make, :model, :data, :wheel_count, :extra_options)
end
现在我可以在我的 _form.html.erb
部分中创建一个文本输入,将数据放入 wheel_count
中,如下所示:
<div class="field">
<%= f.label :wheel_count %>
<%= f.text_field :wheel_count %>
</div>
它按预期工作。然后我想要的是 select 列表(多个 select)或一组复选框,其中 selected 选项存储在 extra_options
.
下
我试过:
<%= f.select :extra_options, options_for_select(["1", "2", "3", "4", "5"], car.extra_options), { include_blank: true }, { multiple: true } %>
产生了以下标记:
<input name="car[extra_options][]" type="hidden" value="" />
<select multiple="multiple" name="car[extra_options][]" id="car_extra_options">
<option value=""></option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
显然,选项标签应该比 1、2、3、4 和 5 更有意义,但更糟糕的是,当我提交表单时,什么都没有存储。
如果我 select 2 和 3 提交,参数如下所示:
"extra_options"=>["", "2", "3"]
这会导致消息 Unpermitted parameter: extra_options
,所以似乎不允许我在此字段中放置数组。
仅仅为了一些额外的选项而创建一个 jsonb 字段似乎很愚蠢,但它自然也会保存各种其他数据。
那么我如何创建多个 select 列表或最好是一组复选框,以便在 jsonb 字段中正确保存数据(当然,在编辑提交时显示已经 selected/checked 的项目)?
试试这个,在 car_params
params.require(:car).permit(:make, :model, :data, :wheel_count, extra_options: [])
对于复选框,试试这个
<%= hidden_field_tag "car[extra_options][]", [] %>
<% ["1", "2", "3", "4", "5"].each do |o| %>
<% default_checked = car.extra_options.include?(o.to_s) rescue false %>
<label class="rightpad">
<%= check_box_tag "car[extra_options][]", o, default_checked %>
</label>
<span>
<%= o %>
</span>
<% end %>
假设我有一个汽车模型,我想在其中显示不同类型的数据。我将 data
列添加到 table:
class AddDataToCars < ActiveRecord::Migration[5.0]
def change
add_column :cars, :data, :jsonb, null: false, default: '{}'
add_index :cars, :data, using: :gin
end
end
然后我为我想要出现的字段添加一个访问器 (extra_options
):
class Car < ApplicationRecord
store_accessor :data, :wheel_count, :extra_options
validates :extra_options, presence: true
end
我确保它是 cars_controller.rb
中允许的参数:
def car_params
params.require(:car).permit(:make, :model, :data, :wheel_count, :extra_options)
end
现在我可以在我的 _form.html.erb
部分中创建一个文本输入,将数据放入 wheel_count
中,如下所示:
<div class="field">
<%= f.label :wheel_count %>
<%= f.text_field :wheel_count %>
</div>
它按预期工作。然后我想要的是 select 列表(多个 select)或一组复选框,其中 selected 选项存储在 extra_options
.
我试过:
<%= f.select :extra_options, options_for_select(["1", "2", "3", "4", "5"], car.extra_options), { include_blank: true }, { multiple: true } %>
产生了以下标记:
<input name="car[extra_options][]" type="hidden" value="" />
<select multiple="multiple" name="car[extra_options][]" id="car_extra_options">
<option value=""></option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
显然,选项标签应该比 1、2、3、4 和 5 更有意义,但更糟糕的是,当我提交表单时,什么都没有存储。
如果我 select 2 和 3 提交,参数如下所示:
"extra_options"=>["", "2", "3"]
这会导致消息 Unpermitted parameter: extra_options
,所以似乎不允许我在此字段中放置数组。
仅仅为了一些额外的选项而创建一个 jsonb 字段似乎很愚蠢,但它自然也会保存各种其他数据。
那么我如何创建多个 select 列表或最好是一组复选框,以便在 jsonb 字段中正确保存数据(当然,在编辑提交时显示已经 selected/checked 的项目)?
试试这个,在 car_params
params.require(:car).permit(:make, :model, :data, :wheel_count, extra_options: [])
对于复选框,试试这个
<%= hidden_field_tag "car[extra_options][]", [] %>
<% ["1", "2", "3", "4", "5"].each do |o| %>
<% default_checked = car.extra_options.include?(o.to_s) rescue false %>
<label class="rightpad">
<%= check_box_tag "car[extra_options][]", o, default_checked %>
</label>
<span>
<%= o %>
</span>
<% end %>