So I have two models: (area.rb and areaimage.rb)

Issue resolved here =>

area.rb – The Area model has_many :areaimages. The areaimage uploader must exist on area#edit

area.rb - the area model - ruby on rails code
area.rb code

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.

areaimage.rb - ruby on rails code
areaimage.rb code

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.

area edit upload form
form code for upload on area.rb
form upload code on area#edit

<% 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.rb

area image uploader.rb
areaimage_uploader.rb code

# encoding: utf-8

class 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.

validation error wrong file type
Validation error Upload should be less than 2MB

I believe this is where the problem is:

areas_controller.rb def update

def update areas controller
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 }
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.

area edit form error code
area#edit form code for @area errors

<% 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 %>
<% end %>
</ul>
</div>
</div>
<% end %>

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.

additional code for the file_field for client side validations
Form field code

<%= 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 } %>

Javascript added at the bottom of page

<!-- This is a client side validation for the areaimage -->
<script>
function validateFiles(inputFile) {
var maxExceededMessage = "This file exceeds the maximum allowed file size (2 MB)";
var extErrorMessage = "Only image file with extensions: .jpg, .jpeg, .gif or .png are allowed";
var allowedExtension = ["jpg", "jpeg", "gif", "png"];

var extName;
var maxFileSize = $(inputFile).data('max-file-size');
var sizeExceeded = false;
var extError = false;

$.each(inputFile.files, function() {
if (this.size && maxFileSize && this.size > parseInt(maxFileSize)) {sizeExceeded=true;};
extName = this.name.split('.').pop();
if ($.inArray(extName, allowedExtension) == -1) {extError=true;};
});
if (sizeExceeded) {
window.alert(maxExceededMessage);
$(inputFile).val('');
};

if (extError) {
window.alert(extErrorMessage);
$(inputFile).val('');
};
}
</script>

See anything you would have done different? Hit me up on Twitter. I am always looking to connect =>