序列化哈希不能保存在postgres数据库中

问题描述 投票:0回答:2

在我的应用程序中,我有一个名为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-on-rails ruby hash
2个回答
1
投票

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

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

但是有更好的方法。由于您使用的是Postgres,您可以利用Postgres JSONB并将数据作为JSON发送。序列化将为您处理,您拥有Postgres's JSON search facilities的所有功能,而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,但它可以使用哈希和数组。


1
投票

areas_of_interest看起来像是被strong_params过滤掉了。我认为你需要的是这样的东西来表明应该允许哪些键:

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

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

© www.soinside.com 2019 - 2024. All rights reserved.