Rails 4.2+:将PostgreSQL JSONB嵌套值映射到表单字段

时间:2016-06-10 21:20:51

标签: ruby-on-rails-4 html-form postgresql-9.4 jsonb

我有一个users表,其中settings字段的类型为JSONB(使用PostgreSQL 9.5)。

我正在尝试在设置页面上创建表单以更新user.settings["notifications"][...]值。

class User < ActiveRecord::Base
end

user = User.create(settings: { notifications: { post_created: true } })

user.settings["notifications"]["post_created"] # => true

要将嵌套的JSONB值映射到表单,我必须这样做:

# views/form.html.erb
<input type="check" name="user[settings][notifications][post_created]" checked="<%= current_user.settings['notifications']['post_created']" %>

class SettingsController
  def update
    current_user.settings["notifications"]["post_created"] = params["user"]["settings"]["notifications"]["post_created"]

    current_user.save
  end
end

无论如何都要利用Rails表单构建器的强大功能,以便我可以这样做:

# will not work, undefined attribute settings['notifications']['post_created']...
<%= form_for current_user, url: settings_path, method: "PUT" do |f| %>
  <%= f.check_box "settings['notifications']['post_created']" %>
<% end %>

我理解Rails正在尝试映射current_user对象中的属性,并且实际上没有名为settings['notifications']['post_created']的“属性”。

但是如何将嵌套的JSONB值映射到CRUD活动的表单字段呢?

一种可行的(但不是真正可行的)方法是为我想要使用的每个嵌套值创建虚拟属性:

class User
  def settings_notifications_post_created
    settings["notifications"]["post_created"]
  end

  def settings_notifications_post_created=(value)
    settings["notifications"]["post_created"] = value
  end
end

# view...
<%= f.check_box :settings_notifications_post_created %>

但是,由于我手动输入每个属性,这会失去传统系统的任何好处。也可以自己编写原始HTML字段和所有getter / setter方法... Googling和Stack Overflow到目前为止还不是很有帮助,似乎没有很多经验做这种东西了...

0 个答案:

没有答案