更新 Rails 中的序列化字段

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

我的 Rails 模型中有一个序列化属性,并正在尝试更新它。

Block#preferences
属性首先作为文本类型通过迁移生成。我们使用 Postgresql 14。

# == Schema Information
#
# Table name: blocks
#
#  id          :bigint           not null, primary key
#  name        :string
#  preferences :text
#  created_at  :datetime         not null
#  updated_at  :datetime         not null
#  page_id     :bigint           not null
#
class Block < ApplicationRecord
  belongs_to :page

  serialize :preferences, JSON
end

我知道强参数的全部意义在于不允许任意参数。但要问一个问题,如何允许通过序列化属性更新动态键而不记录

Unpermitted parameters

下面是传递给

update
操作的参数:

Parameters: {
  "authenticity_token"=>"[FILTERED]", 
  "block"=>{
     "title_text"=>"Hello world!", 
     "description_text"=>"Send us a message.",
     "hero_image"=>"placeholder/block01.jpg",
     "bg_color"=>"#652020"
  },
  "commit"=>"Update Block",
  "id"=>"23"
}

这些在

preferences: {"title_text"=>"Rent with us", "description_text"=>"Send us a message.", "hero_image"=>"placeholder/block01.jpg", "bg_color"=>"#000000"}
对象上保存为
Block
。这些首选项属性只是一个示例 - 还有其他属性,例如
logo_text
links_alignment
。这个列表还在不断增长。

如果您将

update
属性指定为要更新的属性,则
preferences
操作将起作用。

def update
  @block = Block.find(params[:id])

  respond_to do |format|
    if @block.update(preferences: params[:block])
    end
  end
end

private

def block_params
  params.require(:block).permit(
    :name,
    :preferences
  )
end

但是,如果我用

update
调用
block_params
,日志会显示该字段是不允许的:

Unpermitted parameters: :title_text, :description_text, :hero_image, :bg_color.

def update
  @block = Block.find(params[:id])

  respond_to do |format|
    if @block.update(block_params)
    end
  end
end

private

def block_params
  params.require(:block).permit(
    :name,
    :preferences
  )
end

由于这在我们的环境中似乎有点新颖,因此我希望了解序列化如何能够从

params[:block]
映射首选项,但无法使用
update
调用
block_params
。预先非常感谢您的指导!

ruby-on-rails ruby serialization
1个回答
0
投票

参数白名单几乎与您的架构或模型对数据的处理方式几乎无关。

ActionContoller::Parameters
只是一个类似于散列的对象,当您将其传递给 ActiveRecord 持久性方法(新建、创建、更新等)时,如果传递的参数实例没有设置其
permitted
标志,它将引发。这也适用于
ActionContoller::Parameters
的嵌套实例。

此外,Rails 还有一个

action_on_unpermitted_parameters
配置选项,如果存在未包含在白名单中的参数,它将记录或引发。

要完全禁用批量分配保护,您可以使用

permit!

def block_params
  params.require(:block).permit!
end

这允许

ActionContoller::Parameters
实例的所有键以及任何嵌套参数。

如果您想要一个较少核的选项来处理具有任意键的哈希,您可以遍历键:

def block_params
  params.require(:block).permit(*params[:block].keys)
end

这里的区别在于,这仅允许允许的标量值,而不是数组和散列。

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