Rails 4 сильных параметра param не найдена ошибка с несущей волной
У меня возникают проблемы с несущими и рельсами 4 сильных параметра. У меня очень простая модель с кнопкой загрузки несущей. Я хотел бы показать сообщение об ошибке, если кто-то отправит форму загрузки, не выбирая файл для загрузки.
В настоящее время я получаю сообщение об ошибке param not found:photo
с этим сообщением:
# Never trust parameters from the scary internet, only allow the white list through.
def photo_params
params.require(:photo).permit(:image)
end
Эта ошибка происходит из-за того, что сильные параметры Rails 4 требуют наличия параметра изображения для отправки формы, но это не так, потому что пользователь не выбрал изображение.
Я не могу найти способ обойти это и перенаправить его на одно действие и отобразить сообщение об ошибке.
Есть ли способ сделать это с сильными параметрами?
Здесь журнал разработки, когда я пытаюсь использовать форму без выбранной фотографии:
https://gist.github.com/leemcalilly/09b6166ce1af6ca6c833
И вот журнал разработки, когда я выбираю фотографию и успешно загружается:
https://gist.github.com/leemcalilly/1f1e584f56aef15e7af1
Другие соответствующие файлы:
* models/photo.rb - https://gist.github.com/leemcalilly/95c54a5df4e4ee6518da
* контроллеры /photos _controller.rb - https://gist.github.com/leemcalilly/c0723e6dc5478b0f914d
* uploaders/image_uploader.rb - 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
Ответы
Ответ 1
Руководство по настройке предоставляет решение. Используйте метод fetch
так же, как метод require
. Обратите внимание на второй аргумент: он поставляет значение по умолчанию. Итак, если params[:photo]
не будет найден, будет возвращено значение по умолчанию (пустой хеш, как показано ниже):
params.fetch(:photo, {})
Ответ 2
Извините, что это немного поздно, теперь посмотрим на ваш код формы, который выглядит примерно так.
<%= 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 %>
Теперь это не проблема с rails
или carrierwave
или strong_parameter
, это то, как работает html
. Так вот, если у вас есть вход file
, и если к нему привязано nothing
пара name
и value
не отправляется на сервер html
, подумайте об этом как-то вроде checkbox
или disabled
поле
Теперь, поскольку ваша форма содержит только
<%= f.file_field :image %>
и он не содержит никакого другого поля (атрибуты фотомодели)
поэтому хеш photo
не будет создан, если вход file
does not
содержит любое вложение
что также очевидно в вашем журнале
Параметр (без прикрепленного приложения) = >
{"utf8"=>"✓", "authenticity_token"=>"IvOieBvxdA6qzVKrt1dYBuCXlt+uuWCyWjUAuTK0XEU=", "commit"=>"Upload Photo"}
Параметр (с прикрепленным вложением) = >
{"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"}
теперь вы можете увидеть разницу между ними и что разница является причиной вашей ошибки, потому что в
1-й случай
params[:photo].present?
= > false
Второй случай
params[:photo].present?
= > true
и, следовательно, когда вы делаете это params.require(:photo).permit(:image)
, код выдает ошибки
из-за строки упоминается, что .require(:photo)
, который not
присутствует в params
Решение: -
Возможно, вы можете сделать что-то вроде этого
def photo_params
if params[:photo].present?
params.require(:photo).permit(:image)
end
end
Вывод: -
Это не кто-то виноват, потому что это то, как html
работает, если no
вложение no
name=value
пара, отправленная на сервер, и из-за которой параметры photo
не отправляются серверу, поэтому хэш не их и, следовательно, сильный параметр выдает ошибку
Надеемся на эту помощь