Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to configure paperclip to save to different directory depending on environment

I'm collaborating on an app and I occasionally run into trouble stemming from the fact that the original developer was working in linux and I'm in OSX. My current problem has to do with uploading images using ImageMagik and paperclip. When I try to upload a pic to the app, I get the following message.

Permission denied - /assets

I'm pretty sure this means that the app wanted to save the image somewhere in the assets directory but couldn't because it doesn't exist on my machine.

In the model, this is the code that addresses pics.

has_attached_file :avatar, 
  :url  => "/avatars/:id?style=:style",
  :styles => { :large => "190x190#", :medium => "70x70#", :thumb => "106x106#" },
  :path => "/assets/rob/images/Users/:id/:style/:basename.:extension"

Now, I'm assuming this directory exists on the original programmer's computer and wherever the site is hosted at. But I don't have that directory, so I did this:

  :path => "~/robotimus/dev_images/:id/:style/:basename.:extension"

But now I'm in a pickle since I'll ultimately have to revert that line before I deploy. As a solution, I could write a method like this.

def images_path
  Rails.env.production? ? "/assets/rob/images/Users/" : "~/robotimus/dev_images"
end

And then the :path line would look like this:

  :path => images_path + "/:id/:style/:basename.:extension"

Does this sound like a good idea? Also, where should this method be stored? My guess is that it belongs in config/environment.rb, but I'd like to get an expert's opinion.

like image 413
Ben Downey Avatar asked Dec 26 '22 18:12

Ben Downey


1 Answers

I did a similar thing for a project a while back, where in development I stored the images locally, but in the production environment, they were stored on Amazon S3.

What I did was that I created a config/paperclip.yml.

# config/paperclip.yml
common: &common
  :styles:
    :thumb: "50x50#"
    :small: "80x80#"
    :medium: "200x150#"
    :normal: "320x240#"
    :large: "800x600#"
  :default_url: "/images/default_image.png"


development:
  <<: *common

production:
  <<: *common
  :storage: :s3
  :bucket: "your-bucket-name"
  :path: "/:some/:path/:id"
  :url: "s3_domain_url

test:
  <<: *common

Then I loaded that file into my app configuration:

# config/initializers/config.rb
require 'ostruct'

def load_config_yaml(config_file)
  YAML.load(File.read(Rails.root.join('config', config_file)))[Rails.env]
end

AppConfig = OpenStruct.new(load_config_yaml('application.yml'))

AppConfig.paperclip = load_config_yaml('paperclip.yml')

Then I just provided the has_attached_file call with AppConfig.paperclip.

# app/models/image.rb
class Image < ActiveRecord::Base
  has_attached_file :photo, AppConfig.paperclip
end

So if you want to store files in a different path (but still locally), just don't use the s3-stuff.

You can of course skip most of the config stuff and just set the image path in a config somewhere, if you don't want to go all-in on this idea, but I like having configs separate.

like image 162
Frost Avatar answered Jan 13 '23 15:01

Frost