with rails mini_magick image_tag aws ruby-on-rails carrierwave ruby-on-rails-4 strong-parameters

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