序列化哈希不能保存在Postgres数据库上



在我的应用程序中,我有一个名为contacts的表,带有areas_of_interest字段。该字段应存储用户通过表单发送的哈希。但是,我的数据库拒绝这些哈希,并在我想保存时每次都使该字段空白:

模式:

create_table "contacts", force: :cascade do |t|
  ...
  t.text "areas_of_interest"
  t.index ["user_id"], name: "index_contacts_on_user_id"
end

联系模型:

class Contact < ApplicationRecord
  belongs_to :user        
  serialize :areas_of_interest
  ...
end

ContactScontroller:

def update
  respond_to do |format|
    if @contact.update(contact_params)
      format.html do
        redirect_to root_path, notice: 'Contact has been updated'
      end
    else
      format.html do
        render :edit, notice: 'Error'
      end
    end
  end
end
private
def contact_params
  params.require(:contact).permit(
    ...
    :areas_of_interest,
    ...
  )
end

和从客户端发送的哈希看起来像这样:

{"first"=>"1", "second"=>"0", "third"=>"0", "fourth"=>"0", "fifth"=>"1"}

我可能在这里做错了什么,我该如何修复?

您的格式似乎是Ruby Hash的转储。serialize使用YAML完成。看起来像这样。

{ first: "1", second: "0", third: "0", fourth: "0", fifth: "1"}

但是有更好的方法。由于您正在使用Postgres,因此您可以利用Postgres JSONB并将数据发送为JSON。该序列化将为您处理,您拥有Postgres JSON搜索设施的所有功能,JSON是大多数语言都可以产生的标准格式。

{ "first": "1", "second": "0", "third": "0", "fourth": "0", "fifth": "1"}
create_table "contacts", force: :cascade do |t|
  ...
  t.jsonb :areas_of_interest
  t.index [:areas_of_interest], using: :gin
end

Contact中不需要任何特别的东西。像其他任何字段一样使用contact.areas_of_interest,但可以使用哈希和数组。

areas_of_interest看起来像是被 strong_params滤出的。我认为您需要的是这样的东西,以指示应该允许哪些键:

params.require(:contact).permit(
  ...
  areas_of_interest: [:first, :second, :third, :fourth, :fifth],
  ...
)

我也强烈建议使用@schwern提到的jsonb类型。

最新更新