"Too many open files" error uploading with Paperclip - ruby-on-rails

I'm using Rails 3.2.13 and Paperclip to upload/store images for a photo website. The form is nested for albums and photos. The Album model contains the lines
attr_accessible :photos_attributes
accepts_nested_attributes_for :photos
And the Photo model
has_attached_file :photo
So the form has an input
<input type="file" name="album[photos_attributes][][photo]" multiple="true">
It works perfectly for a few photos, but when I try to upload a ton, as a user might since it's a photo website, I get the error "Too many open files."
From what I read, it seems like it's because of the way Paperclip handles opening files and not closing them, so I need to manually close them? The Album#create controller action looks like this:
def create
#album = Album.new(params[:album])
if #album.save
redirect_to album_url(#album)
else
render :new
end
end
What do I need to add here to get this to work? Thanks in advance.

Related

Display multiple images in rails_admin

I am using rails_admin with Rails 5. I have a model Hotel with an association images (has_many). Currently I use the default config of rails_admin, and under Hotel show page, the images of a hotel are displayed in this format:
Image #5381, Image #5382, Image #5383, Image #5384, Image #5385,...
How can I display these images as a gallery given that each image has a thumbnail_url attribute? I means which config I could put in this block to change the display:
show do
field :images do
# Display as a gallery
end
end
Thanks for your time!
Rendering a custom partial is probably the best approach here. Something like:
field :images do
render do
bindings[:view].render partial: 'image_preview', locals: {object: self}
end
end
Then create the partial in app/views/rails_admin/main/_image_preview.html.*, and you're free to control what appears.

Multiple image upload Rails

I have been stuck on a problem for three weeks now, and although I have tried everyday to find an answer to my problem, I haven't found anything that I have been able to make work. If anyone could help me, I would be very, very grateful.
I have built a basic blog in Rails that allows an admin user to publish articles using a form, containing a title text_field, body text_area, and file_field for an image, which uses Paperclip. All very simple and easy and no problems there. However, I have been trying to alter the form to allow an admin user to upload multiple images as part of a new article, but have been unable to find a way to do this.
I need a solution that will allow me to achieve multiple image upload functionality in a form. I have tried many gems and many tutorials, but have been unable to integrate anything into my app without completely breaking it. Can any one help me get out of this dead end I've found myself in for the last three weeks? Do you have any clear tutorials or solutions that will help me overcome this problem?
Thank you very much to anyone that can help me.
Your question is quite broad, without any schema or anything so I'll try to help you as much as possible given that.
If it's a blog, you might have a post model.
You could have a photo model, with a reference to the post model. If you add paperclip to your photo model, then you can save multiple photos.
There are multiple ways to do this. The first one I think of is using nested forms with a gem like cocoon.
The second I think of is using a dropzone, which would upload the photos using Ajax.
By default PaperClip allows you to upload one attachment. However, a clean way I've found to work around this is to create another model which would wrap around the images.
class Article < AR::Base
has_many :images
accepts_nested_attributes_for :images
end
class Image < AR::Base
belongs_to :article
has_attached_file :filename, styles: { medium: "300x300>", thumb: "100x100>" }, default_url: "/images/:style/missing.png"
validates_attachment_content_type :filename, content_type: /\Aimage\/.*\Z/
end
Don't forget to run a migration to create the images table:
rails generate model image article:references
and
rails generate paperclip image filename
Then in your articles/form, where you initially had the field to upload the image, you would have
<%= f.fields_for :images do |p| %>
<%= p.label :filename %><br>
<%= p.file_field :filename%>
<% end %>
In your articles_controller#article_params, along with the current params, you would have, params.require(:article).permit(..., images_attributes: [:filename])
Afterwards, allowing the uploads of multiple images would therefore only require the basic knowledge of nested forms.
To set a default number of file_fields, in your ArticlesController#new after initializing your #article you would have
def new
#article = Article.new
2.times{ #article.images.build}
end
With this setup, when you navigate to your new_articles route, you should see your article ready to upload 2 images.
To learn more about how to use NestedForms to do even more, you should see Ryan Bates tutorial.
This approach provides a cleaner interface, as the other approaches, I guess, would require some sort of hack.
Let me know if I'm able to help or further clarifications required.

Rails cloudinare not uploading image

I've just integrated cloudinary into my rails project and created a view to allow the user to upload an image file.
In my controller I have:
def update
#painting = Painting.find(params[:id])
if params[:image].present?
preloaded = Cloudinary::PreloadedFile.new(params[:image])
raise "Invalid upload signature" if !preloaded.valid?
#painting.image = preloaded.identifier
end
if #painting.update(painting_params)
redirect_to #painting
else
render 'edit'
end
end
In my view:
<%= cl_image_upload_tag(:image) %>
So once the user edits a painting, they can upload the image which will be stored in the #painting model and then it will be saved. After uploading the image, I check cloudinary and find that no image was uploaded. In addition the #painting model has a nil entry for the :image attribute.
Can't see what I'm doing wrong.
Please have a look at the developer tools at the view page, and check whether you have any reported errors there. Specifically, might be related to the jQuery library not being properly included.
You should try to have a look at the sample project. Specifically,
https://github.com/cloudinary/cloudinary_gem/blob/master/samples/photo_album/app/views/photos/new_direct.html.erb#L20

Deleting a public folder or file from a Rails3 view?

I have a user model where users can upload their profile image, using the Paperclip gem. This all works fine and stores the file in the /public/images/#{user.id}/medium or original or small directory.
However I need to create an method to be able to delete these files, could someone help me with this?
Here is the code I have so far:
app/views/users/index.html.erb:
<%= link_to "Delete", method: :file_cleanup, action: :destroy %>
app/controllers/users_controllers.rb:
def file_cleanup
File.delete(Rails.root + 'public/#{current_user.image.url}')
redirect_to :action => :edit
end
I have not added any routes as the page seems to load without any errors.
It should be as simple as:
def delete_image
#user.image.destroy
end
I'd use that as a hook like before_destroy :delete_image.
See: Rails Paperclip how to delete attachment?

Paperclip & Rails Api

I have a photo rails app using paperclip. My model called photo and the request parameter also photo.So when i am trying to upload via curl i use : curl -F "photo[photo]=#/pics/pic.jpg" http://something/photos.xml .
That's works fine! How can i change the photo[photo] parameter to "photo" or "media" or something else? How can i change the endpoint url? (ex. http//something/upload.xml)
thanx!
any help will be highly appreciated, :-)
What you could do is setup another controller and work with it. What paperclip does is just setup an extra "photo" attribute and methods, thus reusing Rails .new and .update_attributes own methods. That way, when you call /photos.xml with that info, what you are doing is just a regular post photo action, with the added benefit of setting up it's picture.
When you do Object.photo = YOUR_PHOTO, you are actually using Paperclip code.
So, you could work with something like:
class ApplicationController < ActiveController::Base
def upload
photo = Photo.new
photo.photo = params[:photo]
# ... extra code
photo.save
render :text => "Ok"
end
end
And add a route like:
map.upload "/upload(.:format)", :controller => "application", :action => "upload"
(or it's Rails3 equivalent if you are using it)
That way, when you do 'curl -F "photo=#/pics/pic.jpg" http://something/upload.xml', you will invoke the upload action and create a photo using the 'photo' parameter. The photo = params[:photo] will take the tempfile you've uploaded and continue with the usual paperclip tasks :)

Resources