Rails check_box_tag - 将数组保存到Postgres中

时间:2017-10-20 04:10:46

标签: ruby-on-rails postgresql

看起来我的表单会执行预期的操作 - 发送正确的值,但不会保存在db中。 Check_box_tag从enum获取数据(我使用枚举,因为我对select字段使用相同的数据):

class UserProfile < ApplicationRecord
  enum locations: { Kursenai: 0, Papiskes: 1, Versiai: 2 }

并在form_for:

<% UserProfile.locations.each do |key, val| %>
  <%= f.label key %>
  <%= check_box_tag('user_profile[locations][]', val, false, id: val) %>
<% end %>

但它无法更新:

  

'[“0”,“1”]'不是有效位置

Postgres的:

t.integer "locations", array: true

所以我认为它失败了,因为行类型是integer,但是这个:

<%= check_box_tag('user_profile[locations][].to_i', val.to_i, false, id: val) %>

已移除错误,但用户字段:locations仍为nil。我错过了什么?

强烈的参数:

..permit(locations: [])

P.S。如果你认为这可以用更好的方式完成 - 请随意展示。

3 个答案:

答案 0 :(得分:1)

你为什么使用枚举?我认为创建一个新的模型位置并通过HABTM关系与UserProfile连接会更好。它将满足数据库规范化并更易于使用。

编辑:

class UserProfile < ApplicationRecord
  has_and_belongs_to_many :locations
end

class Location < ApplicationRecord
  has_and_belongs_to_many :user_profiles
end

您需要创建3个位置记录

Location.create(name: 'Kursenai')
Location.create(name: 'Papiskes')
Location.create(name: 'Versiai')

使用任何标准查询,联接。你可以建立一个像这样的表格: Rails 4 - checkboxes for has_and_belongs_to_many association

Multiple select issue with a HABTM relationship using Rails 4

答案 1 :(得分:1)

<强>为什么吗

因为'[“0”,“1”]'被认为是字符串,它不在你在枚举中提到的值,即0,1,2。

你不能直接实现它,因为枚举需要字段类型来保存单个值。但在你的情况下它是一个数组。

如何实现?

class UserProfile < ApplicationRecord
  # value should store as array not as string.
  serialize :locations, Array

  # define your own enum by creating static var.U can use Array or Hash structure.
  # Here I am using Hash.
  # ENUM_LOCATIONS = ["Kursenai", "Papiskes", "Versiai"]
  ENUM_LOCATIONS = {"Kursenai": 0, "Papiskes": 1, "Versiai": 2}


  # Now modify you getter little bit to return enumed values
  def locations
   res = []
   self[:locations].each{|v| ENUM_LOCATIONS.is_a?(Array) ? res << ENUM_LOCATIONS[v.to_i] : res << ENUM_LOCATIONS.key(v.to_i).to_s}
   res    
  end

end

就是这样。

答案 2 :(得分:0)

看起来有一些命名冲突。我的猜测是因为我在模型locations中声明为哈希,后来允许在强params属性中使用与数组相同的名称。这只是我的猜测。我将枚举重命名为 - enum locs:并将其重命名为UserProfile.locs.each,看起来效果很好:

class UserProfile < ApplicationRecord
  enum locs: { Kursenai: 0, Papiskes: 1, Versiai: 2 }

形式:

<% UserProfile.locs.each do |key, val| %>
  <%= f.label key %>
  <%= check_box_tag('user_profile[locations][]', val, false, id: val) %>
<% end %>

P.S。但正如您所见,现在我将数据保存为string[] - ["1", "2"],即使我的数据库行是 - t.integer "locaions", array: true。想知道为什么Postgres允许将字符串数组写入此行? 不得不重启服务器