ruby on rails - strong - Rails4: ¿Cómo permitir un hash con claves dinámicas en params?
rails strong parameters permit hash (11)
Realizo una solicitud de envío de http con los siguientes parámetros:
{"post" => {"files" => {"file1" => "file_content_1", "file2" => "file_content_2"}}, "id" => "4"}
y necesito permitir matriz de hash en mi código. basado en los manuals que he probado como estos:
> params.require(:post).permit(:files) # does not work
> params.require(:post).permit(:files => {}) # does not work, empty hash as result
> params.require(:post).permit! # works, but all params are enabled
¿Cómo hacerlo correctamente?
UPD1 : archivo1 , archivo2 : son claves dinámicas
Aquí hay otra forma de evitar esto:
def post_params
permit_key_params(params[:post]) do
params.require(:post)
end
end
def permit_key_params(hash)
permitted_params = yield
dynamic_keys = hash.keys
dynamic_keys.each do |key|
values = hash.delete(key)
permitted_params[key] = values if values
end
permitted_params
end
Esto debería funcionar para la post: { something: {...}, something_else: {...} }
Aquí hay una manera simple de hacerlo (funciona para Rails 5):
def my_params
data_params = preset_data_params
params.require(:my_stuff).permit(
:some,
:stuff,
data: data_params
)
end
def preset_data_params
return {} unless params[:my_stuff]
return {} unless params[:my_stuff][:data]
params[:my_stuff][:data].keys
end
En los carriles 5.1.2, esto funciona ahora:
params.require(:post).permit(:files => {})
Ver https://github.com/rails/rails/commit/e86524c0c5a26ceec92895c830d1355ae47a7034
En mi caso, solo había un atributo que tenía claves dinámicas,
def post_params
marking_keys = Set.new
params[:post][:marking].keys.collect {|ii| marking_keys.add(ii)}
params.require(:post).permit(:name, marking: marking_keys.to_a)
end
Entiendo que esta es una publicación anterior. Sin embargo, una búsqueda en Google me llevó a este resultado, y quería compartir mis hallazgos:
Aquí hay una solución alternativa que he encontrado que funciona (Rails 4):
params = ActionController::Parameters.new({"post"=>{"files"=>{"file1"=>"file_content_1", "file2"=>"file_content_2"}}, "id"=>"4"})
params.require(:post).permit(files: params[:post][:files].keys)
# Returns: {"files"=>{"file1"=>"file_content_1", "file2"=>"file_content_2"}}
La diferencia entre esta respuesta y la aceptada es que esta solución restringe el parámetro a solo 1 nivel de claves dinámicas. La respuesta aceptada permite múltiples profundidades.
[Editar] Consejo útil del comentario
"Ah, y debe verificar que existe params [: post] [. Files] de lo contrario las claves fallarán"
Esto es lo que teníamos que hacer en Rails 5.0.0, espero que esto ayude a alguien.
files = params[:post].delete(:files) if params[:post][:files]
params.require(:post).permit(:id).tap do |whitelisted|
whitelisted[:files] = files.permit!
end
La respuesta de Orlando funciona, pero el conjunto de parámetros resultante devuelve false
del permitted?
método. Tampoco está claro cómo procedería si posteriormente tuviera otros parámetros en el hash de post
que desea incluir en el resultado.
Aquí hay otra manera
permitted_params = params.require(:post).permit(:other, :parameters)
permitted_params.merge(params[:post][:files])
No pude obtener ninguna de las muchas respuestas propuestas para trabajar (Rails 5) sin ninguno:
- conocer todas las claves hash por adelantado, o
- negando virtualmente el valor de parámetros fuertes al permitir parámetros arbitrarios.
Estoy usando esta solución.
Utiliza el equipo estándar de parámetros fuertes para limpiar la mayoría de los parámetros, y el atributo Hash se agrega de nuevo explícitamente.
# Assuming:
class MyObject < ApplicationRecord
serialize :hash_attr as: Hash
#...
end
# MyObjectsController method to filter params:
def my_object_params
# capture the hashed attribute value, as a Hash
hash_attr = params[:my_object] && params[:my_object][:hash_attr] ?
params[my_object][:hash_attr].to_unsafe_h : {}
# clean up the params
safe_params = params.require(:my_object).permit(:attr1, :attr2) # ... etc
# and add the hashed value back in
safe_params.to_unsafe_h.merge hash_attr: hash_attr
end
Puede usar una variable temporal para construir su lista permitida así:
permitted = params.require(:post).permit(:id)
permitted[:post][:files] = params[:post][:files].permit!
por diseño, los parámetros fuertes no permiten los valores hash con las claves dinámicas como valores, por lo que ... en este caso necesita incluir los files
lista blanca manualmente.
params.require(:post).tap do |whitelisted|
whitelisted[:files] = params[:post][:files]
end
Send params as array type like name=date[]**strong text**
def user_post
dates = params[:date]
#render json: { ''response'' => params }
i = 0
dates.each do |date|
locations = params[''location_''+"#{i}"]
user_names = params[''user_''+"#{i}"]
currency_rates = params[''currency_''+"#{i}"]
flags = params[''flag_''+"#{i}"]
j = 0
locations.each do |location|
User.new(user_name: user_names[j], currency_name: flags[j],
currency_rate: currency_rates[j], currency_flag: flags[j], location: location).save
j =+ 1
end
i =+ 1
end
def