I’ve got the flexImage plugin working with my RESTful app (thanks to
Alex W.). The problem is when I render the ‘create’ method WITHOUT
uploading an image, I get an invalid image error. My ‘new’ view has
fields for the other attributes in the table (same table where the
images are uploaded), and I would like to enter in those details and
create a new object without having to upload an image. The image is an
option or can be uploaded at a later time. I’ve looked in the FlexImage
model source code and I’ve found where the error occurs (starts on line
4).
unless file.respond_to?(:read) || file_is_a_url
raise InvalidImage, 'Uploaded file contains no binary data. Be
sure that {:multipart => true} is set on your form.’
end
if file.size > 0
# Convert a string URL to a file object
file = open(file) if file_is_a_url
begin
# Create RMagick Image object from uploaded file
if file.path
img = Magick::Image.read(file.path).first
else
img = Magick::Image.from_blob(file.read).first
end
# Ensure file RMagick object validity
raise InvalidImage, 'from_blob method on file returned nil.
Invalid format.’ if img.nil?
# Convert to a JPG
img.format = 'JPG'
# Set image quality and save result to record
self.rmagick_image = img
# Perform image pre-processing
process! @@upload_options unless @@upload_options.empty?
rescue
# File was not an image, mark for adding validation error
invalidate_image_field
ensure
GC.start
end
else
invalidate_image_field
end
self[data_field]
end
def [](field_name, *args) #:nodoc:
if field_name.to_sym == data_field.to_sym && @@file_store
@data ||= rmagick_image.to_blob
else
super(field_name, *args)
end
end
def []=(field_name, value, *args) #:nodoc:
if field_name.to_sym == data_field.to_sym && @@file_store
@data = value
else
super(field_name, value, *args)
end
end
Anyone know how I would be able to create a new object without
necessarily uploading an image at the same time?
unless file.respond_to?(:read) || file_is_a_url
raise InvalidImage, 'Uploaded file contains no binary data. Be
sure that {:multipart => true} is set on your form.’
end
[snip]
Anyone know how I would be able to create a new object without
necessarily uploading an image at the same time?
Name your form field something other than ‘data’. I’m using flex_image
(outside of REST) and my form field is named “image_file”. My forms are
two part, first part is data, second part is the image file. In the
second part I simply do this:
unless params['image_file'].original_filename.empty? then
@photo.data = params['image_file']
end
Anyone know how I would be able to create a new object without
necessarily uploading an image at the same time?
Like any uploaded file in Rails, you need to check that there is
actually data there, by checking the the uploaded file has a size > 0.
def upload_image
params[:my_model].delete(:image) if params[:my_model][:image].size >
0
if params[:my_model][:image].size > 0
MyModel.create(params[:my_model])
end
end
Sadly, rails will populate the parameter from the file field with a file
object, whether something was uploaded or not.
Now that you bring it up, there really ought to be a more graceful way
to handle this. Perhaps by making the upload optional, and only have it
required with:
The problem is when I render the ‘create’ method WITHOUT
uploading an image, I get an invalid image error.
Ok, I just checked in an alteration to the plugin. To get the behavior
you want use:
class Foo < FlexImage::Model
self.require_image_data = false
end
class FooController < AC::B
def create @user = User.create(params[:user])
end
end
This will simply leave the data field as nil, or not write a file to the
disk, if there is no uploaded file. This means you no longer have to
check if the file exists in the controller. Simply pass the entire
params hash that you want into Model.create or Model.new and
FlexImage::Model will ignore it if its empty and require_image_data is
false.
However this is only useful if you want to have records without images.
If you have a model where the reason for the model existing is the
image, like an Avatar of a ProductImage, then this would not be a good
choice. The image validation errors should be your friend in those
cases.
It works in my tests. Please test it in your app and let me know if it
has the intended behavior.
I’m always open to making this plugin better. Don’t hesitate to ask.