Rails モデルにシリアル化された属性があり、それを更新しようとしています。 Block#preferences 属性は、最初は移行によってテキスト タイプとして生成されました。 Postgresql14を使用しています。
# == 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
強力なパラメーターの要点は、任意のパラメーターを許可しないことだと理解しています。しかし、質問したいのですが、許可されていないパラメーターをログに記録せずに、シリアル化された属性を通じて動的キーを更新できるようにするにはどうすればよいですか。
以下は、更新アクションに渡されるパラメーターです。
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"
}
これらは設定として保存されます: {“title_text”=>“Rent with us”、“description_text”=>“Send us a message.”、“hero_image”=>“placeholder/block01.jpg”、“bg_color”=>” Block オブジェクトの #000000”}。これらの設定属性は単なる例であり、logo_text や links_alignment などの他の属性もあります。このリストは増え続けています。
更新アクションは、更新する属性として設定属性を指定した場合に機能します。
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
ただし、block_params を指定して update を呼び出すと、フィールドが許可されていないことがログに表示されます。
許可されていないパラメータ: :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
これは私たちの環境では少し斬新なように見えるので、serialize が params[:block] から設定をマッピングできるが、block_params を使用して update を呼び出すことができない方法を学習しようとしています。ご指導をよろしくお願いいたします。
パラメーターのホワイトリスト登録は、スキーマやモデルが一般的にデータに対して行っている処理とはほとんど関係がありません。
ActionContoller::Parameters は単なるハッシュのようなオブジェクトであり、これを ActiveRecord 永続化メソッド (new、create、update など) に渡すと、渡されたパラメーター インスタンスに許可フラグが設定されていない場合に発生します。これは、ActionContoller::Parameters のネストされたインスタンスにも当てはまります。
さらに、ActionContoller::Parameters には action_on_unpermitted_parameters 設定オプションがあり、permit を呼び出したときにホワイトリストにないキーが存在する場合に、ログに記録したり、発生させたり、何も行わなかったりします。
一括割り当て保護を完全に無効にするには、permit! を使用できます。
def block_params
params.require(:block).permit!
end
これにより、ActionContoller::Parameters のこのインスタンスのすべてのキーとネストされたパラメーターが許可されます。
任意のキーを持つハッシュを処理する核の少ないオプションが必要な場合は、受信パラメータのキーのリストを渡すだけです。
def block_params
params.require(:block).permit(*params[:block].keys.map(&:to_sym))
end
ここでの違いは、許可されるスカラー値のみが許可され、配列やハッシュは許可されないことです。