ruby-on-rails - mini_magick - rails carrierwave image_tag
Parámetros fuertes de Rails 4 param no encontrado error con carrierwave (2)
Estoy teniendo problemas con carrierwave y rieles 4 parámetros fuertes. Tengo un modelo muy simple con un botón de carga de la onda portadora. Me gustaría mostrar un mensaje de error si alguien envía el formulario de carga sin elegir un archivo para cargar.
En este momento, recibo un param not found:photo
error de param not found:photo
con este mensaje:
# Never trust parameters from the scary internet, only allow the white list through.
def photo_params
params.require(:photo).permit(:image)
end
Este error ocurre porque los parámetros fuertes de Rails 4 requieren que el parámetro de imagen esté presente para enviar el formulario, pero no está ahí porque el usuario no ha seleccionado una imagen.
No puedo encontrar una manera de solucionar esto y hacer que se redirija a la misma acción y muestre un mensaje de error.
¿Hay una manera de hacer esto con parámetros fuertes?
Aquí está el registro de desarrollo cuando trato de usar el formulario sin una foto seleccionada: https://gist.github.com/leemcalilly/09b6166ce1af6ca6c833
Y aquí está el registro de desarrollo cuando elijo una foto y la subo con éxito: https://gist.github.com/leemcalilly/1f1e584f56aef15e7af1
Otros archivos relevantes: * models / photo.rb - https://gist.github.com/leemcalilly/95c54a5df4e4ee6518da * controllers / photos_controller.rb - https://gist.github.com/leemcalilly/c0723e6dc5478b0f914d * uploaders / image_uploaderr - https://gist.github.com/leemcalilly/5e43f6524734991773ae * views / photos / index.html.erb - https://gist.github.com/leemcalilly/a8c4c808e5e8a802933b * views / photos / _form.html.erb - https://gist.github.com/leemcalilly/cd0fd518c1b47d9bfb62 * initializers / carrierwaver.rb - https://gist.github.com/leemcalilly/49e04fa1dda891dd108b
Las guías de rieles proporcionan la solución . Use el método fetch
de la misma manera que el método require
. Tenga en cuenta un segundo argumento: proporciona el valor predeterminado. Por lo tanto, si no se encuentran los params[:photo]
, se devolverá el valor predeterminado (un hash vacío, a partir del siguiente ejemplo) :
params.fetch(:photo, {})
Perdón, he visto que es un poco tarde, Ok, ahora está viendo el código del formulario, que se parece a esto
<%= form_for @photo, :html => {:multipart => true} do |f| %>
<% if @photo.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@photo.errors.count, "error") %> prohibited this photo from being saved:</h2>
<ul>
<% @photo.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<fieldset>
<legend>Upload a Photo</legend>
<div class="field">
<%= f.file_field :image %>
</div>
</fieldset>
<%= f.submit "Upload Photo", :class => "btn btn-small" %>
<% end %>
Ahora bien, esto no es un problema con rails
o carrierwave
o strong_parameter
, es algo como funciona html
. Es así, si tiene entrada de file
y si nothing
se le adjunta nothing
, el par de name
y value
no se envía al servidor mediante HTML
piense en ello como una checkbox
o un campo disabled
Ahora, ya que su formulario solo contiene <%= f.file_field :image %>
y no contiene ningún otro campo (atributos del modelo de foto)
por lo tanto, el hash de la photo
no se construiría cuando la entrada del file
does not
contenga ningún archivo adjunto
lo que es evidente en su registro también
Parámetro (sin archivo adjunto) =>
{"utf8"=>"✓", "authenticity_token"=>"IvOieBvxdA6qzVKrt1dYBuCXlt+uuWCyWjUAuTK0XEU=", "commit"=>"Upload Photo"}
Parámetro (con adjunto adjunto) =>
{"utf8"=>"✓", "authenticity_token"=>"I4O0w+Wk8nJaD6HJRSC+FfuAip5NVE6TkCUFDEN+sW0=", "photo"=>{"image"=>#<ActionDispatch::Http::UploadedFile:0x007fc730b5de08 @tempfile=#<Tempfile:/var/folders/0m/n32lgww55vzf5pfc4kh17gm00000gr/T/RackMultipart20130801-32602-1nj6u2b>, @original_filename="bag.jpg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=/"photo[image]/"; filename=/"bag.jpg/"/r/nContent-Type: image/jpeg/r/n">}, "commit"=>"Upload Photo"}
Ahora puede ver la diferencia entre los dos y que la diferencia es la razón de su error porque en
1er caso
params[:photo].present?
=> falso
2do caso
params[:photo].present?
=> verdadero
y por lo tanto cuando haces esto params.require(:photo).permit(:image)
el código arroja los errores
debido a la línea mencione que .require(:photo)
que not
está presente en params
Solución:-
Quizás puedas hacer algo como esto.
def photo_params
if params[:photo].present?
params.require(:photo).permit(:image)
end
end
Conclusión: -
No es culpa de nadie porque así es como funciona el HTML
si no
adjunta no
par adjunto no
name=value
enviado al servidor y debido a que los parámetros de photo
no se envían al servidor, por lo tanto, el hash no los tiene y, por lo tanto, un parámetro fuerte genera el error.
Espero que esto ayude