我有一个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到目前为止还不是很有帮助,似乎没有很多经验做这种东西了...