2

I have data stored in the following file: guess what data it is? :)

S3_CREDENTIALS = Rails.root.join("config/s3.yml")

To confirm it's working, I fired up rails console and found S3_CREDENTIALS is a Pathname object. But I'm having trouble confirming that the data is there. How would I access the bucket data, for example?

Loading development environment (Rails 3.1.0.beta1)
>> S3_CREDENTIALS.isdir
NoMethodError: undefined method `isdir' for #<Pathname:0x10212f6f8>
    from (irb):1
>> S3_CREDENTIALS.size
=> 282
>> S3_CREDENTIALS.data
NoMethodError: undefined method `data' for #<Pathname:0x10212f6f8>
    from (irb):3
>> S3_CREDENTIALS[:bucket]
NoMethodError: undefined method `[]' for #<Pathname:0x10212f6f8>
    from (irb):4
>> 

On a related note, would this still work if I changed the file from s3.yml to s3.json?

Geoff
  • 9,470
  • 13
  • 52
  • 67

1 Answers1

4

If you are using this as s3 storage with Paperclip you want to leave it as yml. Inside your initializers (config/initializers) create a file called:

app_config.rb

AppConfig = YAML.load(File.read(Rails.root + 'config' + 'config.yml'))[Rails.env].with_indifferent_access

Your config for all your s3 stuff should be in the format:

config.yml

development:
  s3:
    access_id: access-id
    secret_key: secret
    bucket_name: your-bucket-name-for-development
staging:
  s3:
    access_id: access-id
    secret_key: secret
    bucket_name: your-bucket-name-for-staging
production:
  s3:
    access_id: access-id
    secret_key: secret
    bucket_name: your-bucket-name-for-production

At this point you should be able to go into your console and access your s3 data by just putting in:

AppConfig[:s3]

And you should get a hash back with all your data like:

{"access_id"=>"access-id", "bucket_name"=>"your-bucket-name-for-development", "secret_key"=>"secret"}

I just have the above as an example if you want to test your s3 stuff on development, but ordinarily you would just save to your local file directory on development, and use s3 for remote staging and production environments.

Accessing the bucket data is a different conversation and depends how you have your bucket data associated to your model. If for example your bucket data was associated to a Photo model like so:

photo.rb

require 'paperclip'

class Photo < ActiveRecord::Base
  belongs_to :album
  before_save :set_orientation

  if AppConfig['s3']
    has_attached_file :data, 
      :styles => { 
        :thumb => "200x200>",
        :medium => "700x700>" 
      },
      :storage => :s3, 
      :default_style => :medium,
      :bucket => AppConfig['s3']['bucket_name'],
      :s3_credentials => { :access_key_id => AppConfig['s3']['access_id'], :secret_access_key => AppConfig['s3']['secret_key'] },
      :s3_headers => { 'Cache-Control' => 'max-age=315576000', 'Expires' => 10.years.from_now.httpdate },
      :path => "/:class/:id/:style/:filename"
  else
    has_attached_file :data,
      :styles => { 
        :thumb => "200x200>",
        :medium => "700x700>"
      },
      :storage => :filesystem, 
      :default_style => :medium
  end

  private
  def set_orientation
    self.orientation = Paperclip::Geometry.from_file(self.data.to_file).horizontal? ? 'horizontal' : 'vertical'
  end
end

I have my attach file name called data, as illustrated in has_attached_file :data. So to access some bucket data, I would call:

Photo.first.data(:thumb)

And that would pull the s3 url that the thumbnail photo was storing for the first Photo object that was returned. The above example is also using the 'paperclip' gem and 'aws-s3' gem.

config.gem 'aws-s3', :version => '>=0.6.2', :lib => 'aws/s3'
config.gem 'paperclip'

Hope this help you on your way.

Chris Barretto
  • 9,379
  • 3
  • 42
  • 45