Rails : Error multiple file upload, empty array - ruby-on-rails

i have big problem, my rails application cannot upload photos correctly i get this error every time.
you can se on right of photos cannot upload cloudinary url
I have to do this since the admin and not from the site itself to add pictures
cars_controller.rb
def index
#cars = Car.all()
end
def show
#car = Car.friendly.find(params[:id])
#photos = #car.photos
end
end
photos_uploader.rb
include Cloudinary::CarrierWave
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
def extension_whitelist
%w(jpg jpeg gif png)
end
photo.rb
mount_uploaders :photos, PhotosUploader
belongs_to :car
car.rb
extend FriendlyId
friendly_id :title, use: :slugged
mount_uploader :photo, PhotoUploader
has_many :photos
You can see my error

mount_uploaders are not currently supported in the Cloudinary Ruby gem. The issue can be tracked here https://github.com/cloudinary/cloudinary_gem/issues/304.
There is a sample project (https://github.com/taragano/Cloudinary_multiple_uploads) that illustrates a temporary workaround. The models are album and photo, where album has a has_many relationship to photos and photo has a belongs_to relationship to album.
The models (https://github.com/taragano/Cloudinary_multiple_uploads/tree/master/app/models) should look like this:
class Photo < ActiveRecord::Base
belongs_to :album
mount_uploader :image, ImageUploader
end
class Album < ActiveRecord::Base
has_many :photos, dependent: :destroy
end
While in the controller (https://github.com/taragano/Cloudinary_multiple_uploads/blob/master/app/controllers/albums_controller.rb), you'll need to iterate over each photo and store it to the album that it belongs to:
def store_photos
photos = params[:album][:photos]
photos.each{|photo| #album.photos.create(image: photo)} if photos
end

Related

How to best way define the main object in the polymorphic relations?

I have models:
dress.rb
class Dress < ActiveRecord::Base
has_many :images, as: :imageable
end
publication.rb
class Publication < ActiveRecord::Base
has_many :images, as: :imageable
end
image.rb
class Image < ActiveRecord::Base
mount_uploader :name, ImageUploader
belongs_to :imageable, polymorphic: true
end
I have two ideas how its write:
Add main_image_id (:integer) to Image, Publication and other models. Also can create a relation has_one :main_image, class_name: 'Image', foreign_key: :main_image_id. But this is bad way because this field need add to every created Model which has polymorphic relations with Image.
Add main (:boolean) to Image. And check every time true or false. This is bad way too because table images will have unused fields.
Who has any thoughts?
2nd way is better. this way you can order images by this field and make scopes.
# image.rb
scope main, ->{where(main: true)}
# publication.rb
scope images, ->{images.order(:main)}
#images.main #=> will give you needed result as
#publiscations.images #=> will give you first image as main.
And if you think about extra column, you will need to add it anyway. So why not to use it where it is more useful
STI
Maybe try STI
#app/models/asset.rb
Class Asset < ActiveRecord::Base
mount_uploader :name, ImageUploader
end
#app/models/image.rb
Class Image < Asset
belongs_to :imageable, polymorphic: true
delegate :url, to: :asset #-> not used Carrierwave, so I don't know how this is done
end
#app/models/dress.rb
Class Dress < ActiveRecord::Base
has_many :images, as :imageable
end
#app/models/publication.rb
Class Publication < ActiveRecord::Base
has_many :images, as :imageable
end
This will give you the ability to call the following:
#app/controllers/dresses_controller.rb
Class DressesController < ApplicationController
def index
#dresses = Dress.all
end
end
#app/views/dresses/index.html.erb
<% #dresses.each do |dress| %>
<%= dress.images.each do |image| %>
<%= image_tag image.url %>
<% end %>
<% end %>

Carrierwave - How to reference a model's image from a different model

I have a User model and a Project model. The User model has a PhotoUploader as a carrierwave uploader, and the Project model has a LogoUploader as a carrierwave uploader.
I also have a Poster model that references a User or a Project. With this Poster I can make a post with an User or a Project, in the same way (showing a name, a description and a image).
The problem is that I want to reference a photo from an User or a logo from a Project, using a string attribute like "image", that is an Uploader object from carrierwave.
I don't want to duplicate images.
How can I do this? Is this the right way to do it?
Polymorphic Association is what you need. http://guides.rubyonrails.org/association_basics.html#polymorphic-associations
http://railscasts.com/episodes/154-polymorphic-association-revised
models/media.rb
class Media < ActiveRecord::Base
attr_accessible :content
belongs_to :mediable, polymorphic: true
end
models/user.rb
class User < ActiveRecord::Base
attr_accessible :content, :name
has_many :medias, as: :mediable
end
models/project.rb
class Project < ActiveRecord::Base
attr_accessible :content, :name
has_many :medias, as: :mediable
end
routes.rb
resources :users do
resources :medias
end
resources :projects do
resources :medias
end
when you save a media to user, you'll create a new media row:
id mediable_type mediable_id some_other_field
1 User 1 something here
then you can call current_user.medias

Rails Carrierwave stor_dir location not valid (Model.#{association} returns nil)

I am using carrierwave to upload images to my webapp.
It has become necessary to upload them to the location of the parent model.
Ie.
The parent is house which has many images.
So I want to store the images in
public/uploads/houses/images/[:house_id]/
This is my current setup.
..uploaders/image_uploader.rb
def store_dir
puts "uploads/house/#{model.house_id}/#{mounted_as}/#{model.id}"
"uploads/house/#{model.house_id}/#{mounted_as}/#{model.id}"
end
The puts statement prints out the correct path that I would like but the path saved does not match.
It appears that the model.house_id is returning nil
House Model
class House < ActiveRecord::Base
attr_accessible :address, :description, :title, :price, :image, :image_id, :images, :image_cache
has_many :images
mount_uploader :image, ImageUploader
end
Image Model
class Image < ActiveRecord::Base
attr_accessible :house_id, :image
mount_uploader :image, ImageUploader
belongs_to :house
end
How do I get the correct path/ What am I doing wrong :(
Please try:
def cache_dir
"#{Rails.root}/public/uploads/houses/images"
end
def store_dir
"#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end

Carrierwave and has_many

I have Product model like this:
class Product < ActiveRecord::Base
has_many :images, :class_name => 'ProductImage', :order => 'position DESC', :dependent => :destroy
def image_thumb
images.first.image.thumb.url
end
def image
images.first.image.url
end
end
ProductImage model:
class ProductImage < ActiveRecord::Base
attr_accessible :image, :position, :product_id, :title
belongs_to :product
default_scope order('position ASC')
mount_uploader :image, ProductImageUploader
end
Uploader model:
class ProductImageUploader < CarrierWave::Uploader::Base
...
def default_url
asset_path([version_name, "default.jpg"].compact.join('_'))
end
end
But if I don't upload any image for product, I will get 'nil' in image_thumb and image methods. How get default_url if no one image uploaded and relation between Product and ProductImage models are one-to-many?
If you don't have access to an uploader, an uploader can't help you, so you have to do it by hand. You're already using a presenter (more or less), so this is extremely easy:
def image_thumb
if images.any?
images.first.image.thumb.url
else
asset_path("default.jpg")
end
end
def image
if images.any?
images.first.image.url
else
asset_path("thumb_default.jpg")
end
end
Similar code works for belongs_to relationships.
What is the value you are getting for default_url?
Maybe the path is not evaluating correctly.
Try something like this (of course correct the path below to what it should be):
class ProductImageUploader < CarrierWave::Uploader::Base
...
def default_url
"/assets/" + [version_name, "default.jpg"].compact.join('_')
end
end

Dynamic Store Dir with CarrierWave

Only new to Rails but I've started been using CarrierWave for my upload handling. I am trying to make a media hosting app whereby:
A Show belongs to a User
A Show has many Episodes
An episode belongs to video
At the moment I am using single table inheritance to store my video content into a meta data type Asset table, all is saving well. The issue I'm trying to get to is when I save the video via CarrierWave I want to be able to get both the show slug and the episode slug into the save path.
Currently I have this set up with my shows and episode uploads:
def store_dir
"shows/#{model.friendly_id}/cover/"
end
And previously before STI i would just store the filename in a video field in the episodes table and have it store via:
def store_dir
"shows/#{model.show.slug}/episodes/#{model.id} - #{model.friendly_id}"
end
Only problem now I cannot get the episode information from my video model in the CW uploader.
My models are:
Show.rb
class Show < ActiveRecord::Base
#Associations
belongs_to :user
belongs_to :category
has_many :episodes
#Slugs
extend FriendlyId
friendly_id :title, use: :slugged
#Carrierwave
mount_uploader :image, ShowImageUploader
end
Episode.rb
class Episode < ActiveRecord::Base
belongs_to :show
belongs_to :image, :class_name => "Episode::Image"
belongs_to :audio, :class_name => "Episode::Audio"
belongs_to :video, :class_name => "Episode::Video"
accepts_nested_attributes_for :video, :image, :audio
before_save :add_guid, :on => :create
#Slugs
extend FriendlyId
friendly_id :title, use: :slugged
validates :title, :presence => true, :length => {:within => 5..40}
protected
def add_guid
self.guid = UUIDTools::UUID.random_create.to_s
end
end
episode/video.rb
class Episode::Video < Asset
mount_uploader :video, EpisodeVideoUploader, :mount_on => :filename
end
asset.rb
class Asset < ActiveRecord::Base
end
So I guess how can I get the appropriate data after upload into:
"shows/#{model.show.slug}/episodes/#{model.id} - #{model.friendly_id}"
Thanks!

Resources