Search code examples
ruby-on-railspathname

How do you access a Ruby on Rails Rails.root.join yml file from the console?


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?


Solution

  • 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.