Issue resolved here =>
area.rb – The Area model has_many :areaimages. The areaimage uploader must exist on area#edit
class Area < ActiveRecord::Base
belongs_to :map
has_many :areaimages, dependent: :destroy
accepts_nested_attributes_for :areaimages
end
areaimage.rb – AreaImage model – belongs_to :area – I need to be able to upload this on area#edit, and if it fails validation, I need it to display the error message on the area#edit page.class Areaimage < ActiveRecord::Base
mount_uploader :areaimage, AreaimageUploader
belongs_to :area
validates_size_of :areaimage, maximum: 2.megabytes, message: "Upload should be less than 2MB"
end
While updating/creating an Area, I can upload an areaimage:Here is what I see on the area#edit. You can see the upload field. I included the code from the form. It allows for multiple area_images, although here I am only allowing one.
<% if @areaimages.exists? %>
<%= f.label :area_Image, :class => 'control-label col-lg-2' %>
<%div class="col-lg-4">
<% @areaimages.each do |p| %>
<%div class="form-control">
<%= image_tag p.areaimage_url, :class => 'form-control-image' %>
<%= link_to ''.html_safe,
edit_areaimage_path(p), :class => 'form-control-button',
:title => 'Edit Attachment' %>
<%/div>
<% end %>
<%/div>
<% else %>
<%= f.label :area_image, :class => 'control-label col-lg-2' %>
<%div class="col-lg-4">
<%= f.file_field :areaimage, :multiple => true, name: "areaimages[areaimage][]", :class => 'form-control' %>
<%/div>
<% end %>
areaimage_uploader.rbclass AreaimageUploader < CarrierWave::Uploader::Base
if Rails.env.production?
storage :fog
else
storage :file
end
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
def extension_white_list
%w(jpg jpeg gif png)
end
end
If my upload fails validation, how do I display the error message?*If it fails validation (in production) it pushes you to the 422 page.
**In development I can see two validation errors failing currently.
I believe this is where the problem is:
areas_controller.rb def update
def update
respond_to do |format|
if @area.update(area_params)
if params.has_key?(:areaimages)
params[:areaimages]['areaimage'].each do |a|
@areaimage = @area.areaimages.create!(:areaimage => a)
end
end
format.html { redirect_to area_path(@area), notice: 'Area was successfully updated.' }
format.json { render :show, status: :ok, location: @area }<br>
else
format.html { render :edit }
format.json { render json: @area.errors, status: :unprocessable_entity }
end
end
end
I believe this is where the problem is:Line 73 if params.has_key?(:areaimages)
– this really needs to say if the params.has_key?(:areaimages) && the key is valid.
– I need it to do those two validations. File size and only the permitted file type. If not and it fails validation, I need it to display the information on the new/edit form.
<% if @area.errors.any? %>
<div id="error_expl" class="panel panel-danger">
<div class="panel-heading">
<h3 class="panel-title"><%= pluralize(@area.errors.count, "error") %> prohibited this area from being saved:</h3>
</div>
<div class="panel-body">
<ul>
<% @area.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
</div>
<% end %>
Please email jeremygradisher@gmail.comor you can answer it here:
http://stackoverflow.com/questions/42357546/carrierwave-error-handling-on-accepts-nested-attributes-for
or here:
http://stackoverflow.com/questions/38062081/message-not-displaying-after-validation-failure-carrierwave-ruby-on-rails
Problem solved – How I fixed this:
I fixed this with a little Client Side Validation
With a little addition of code on the file_field: onchange: “validateFiles(this);”, data: { max_file_size: 2.megabytes } and an addition of Javascript at the bottom of the page the form is a part of I was able to solve the validation error message issue.
This is safe as it is also checked server side so you never upload what can not pass validation. I just couldn’t get the error message to work correctly when the image was too large or the wrong file type. I would still prefer to solve it server side and display the message that way for continuity.
<%= f.label :area_image, :class => 'control-label col-lg-2' %>
<%= f.file_field :areaimage, :multiple => true, name: "areaimages[areaimage][]",
:class => 'form-control', onchange: "validateFiles(this);",
data: { max_file_size: 2.megabytes } %>
<!-- This is a client side validation for the areaimage --><br>
<%script><br>
function validateFiles(inputFile) {<br>
var maxExceededMessage = "This file exceeds the maximum allowed file size (2 MB)";<br>
var extErrorMessage = "Only image file with extensions: .jpg, .jpeg, .gif or .png are allowed";<br>
var allowedExtension = ["jpg", "jpeg", "gif", "png"];<br><br>
var extName;<br>
var maxFileSize = $(inputFile).data('max-file-size');<br>
var sizeExceeded = false;<br>
var extError = false;<br><br>
$.each(inputFile.files, function() {<br>
if (this.size && maxFileSize && this.size > parseInt(maxFileSize)) <br>{sizeExceeded=true;};<br>
extName = this.name.split('.').pop();<br>
if ($.inArray(extName, allowedExtension) == -1) {extError=true;};<br>
});<br>
if (sizeExceeded) {<br>
window.alert(maxExceededMessage);<br>
$(inputFile).val('');<br>
};<br>
if (extError) {<br>
window.alert(extErrorMessage);<br>
$(inputFile).val('');<br>
};<br>
}<br>
<%/script>