AnthonyGalli.com
AnthonyGalli.com

Reputation: 2866

Upload via assets/images or via AWS Amazon?

So on my website a user can upload "inspirations" aka pictures or text that a user finds inspirational.

Now I'm going to create a feature, like pinterest, where a user can click on a preloaded image or text to "pin it", except I'll have my button say - "make my inspiration".

I'm not sure though on this page I'm creating: pages/suggested_inspirations.html.erb if I should upload suggested images via assets/images or via AWS Amazon? In the latter case I would add a checkbox to inspirations/new.html.erb only visible to admin users, which if clicked would save the inspiration to my suggested_inspirations page.

I use AWS Amazon-S3 for user uploaded images. Right now I'm on the free plan.

Upvotes: 1

Views: 71

Answers (2)

Richard Peck
Richard Peck

Reputation: 76784

This sounds like you're getting confused with the structure


where a user can click on a preloaded image or text to "pin it"

This should use a join table:

#app/models/user.rb
class User < ActiveRecord::Base
   has_many :uploads

   has_many :likes
   has_many :liked_uploads, through: :likes, class_name: "Upload", association_foreign_key: :upload_id
end

#app/models/like.rb
class Like < ActiveRecord::Base
   belongs_to :user
   belongs_to :upload
end

#app/models/upload.rb
class Upload < ActiveRecord::Base
   belongs_to :user #-> uploader

   has_many :likes
   has_attached_file :image #-> paperclip
end

This way, you'll be able to have as many "uploads" as you want (IE the user can upload either an image or text), and then have as many users "liking" it.

The image will be uploaded once (single source of truth), anyone "liking" it will just be added a reference through the join model:

#config/routes.rb
resources :inspirations do
   match :like, via: [:post, :delete], on: :member #-> url.com/inspirations/:id/like
end

#app/controllers/inspirations_controller.rb
class InspirationsController < ApplicationController
  before_action :authenticate_user!, only: :like

  def like
     @inspiration = Upload.find params[:id]
     if request.post? 
        current_user.likes << @inspiration
     elsif request.delete?
        current_user.likes.delete @inspiration
     end
  end
end

You can change the above how you want.


a user can upload "inspirations" aka pictures

This can only happen if you have a model to support it. Paperclip and Carrierwave are the best gems for this.

You cannot upload images to the assets/images folder. The asset pipeline is meant to provide images for use within your views etc.

Paperclip works with S3 out of the box - implement an Upload model and you'll have the ability to upload images directly to S3.

Upvotes: 0

Yerken
Yerken

Reputation: 1942

Copying from the comment section

it seems your question more about the size of your application. If you are serving millions of images and speed is a factor, I would suggest to go for Amazon S3. Since you are already on AWS stack, it will ease up the scaling in your case. Storing images on your server will prevent you from scaling, will slow down the image serving part and furthermore you will have to handle image viewing restriction (admin vs non-admin) which can be easily implemented if you are on s3.

I'd go with the s3 right from the beginning. Additionally set up a cloudfront for your bucket. aws.amazon.com/cloudfront Given your needs costs should be really cheap. Also don't forget to set correct cache control headers when you upload images on s3 :)

Upvotes: 0

Related Questions