Category: Rails

Rails 4.1, initializers, and secrets.yml

Posted by – April 9, 2014

I'm using 4.1 on a new project. When I tried to set up an initializer using the values in secrets.yml, I got this error:

/Users/barry/.rvm/gems/ruby-2.1.1@rails4.1/gems/railties-4.1.0.rc2/lib/rails/application.rb:311:in `secrets': uninitialized constant Rails::Application::YAML (NameError)
from /Users/barry/projects/archiv8-billing/config/initializers/chargify.rb:2:in `block in '
from /Users/barry/.rvm/gems/ruby-2.1.1@rails4.1/gems/chargify_api_ares-1.0.4/lib/chargify_api_ares/config.rb:6:in `configure'
from /Users/barry/projects/archiv8-billing/config/initializers/chargify.rb:1:in `

I fixed it by adding require 'yaml' to the top of my initializer:

require 'yaml'
Chargify.configure do |c|
  c.api_key   = Rails.application.secrets.chargify_key
  c.subdomain = Rails.application.secrets.chargify_subdomain

Validating URLs for non-ActiveRecord objects

Posted by – July 9, 2010

I'm using Mongoid and MongoDB on a new project, so my models are not derived from ActiveModel. On previous projects I just used the validates_url_format_of plugin, but for this project I put the code from the module into an initializer (config/initializers/validation.rb) and used extend.

module ValidatesUrlFormatOf
  IPv4_PART = /\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]/  # 0-255
  REGEXP = %r{
    https?://                                                    # http:// or https://
    ([^\s:@]+:[^\s:@]*@)?                                        # optional username:pw@
    ( (([^\W_]+\.)*xn--)?[^\W_]+([-.][^\W_]+)*\.[a-z]{2,6}\.? |  # domain (including Punycode/IDN)...
        #{IPv4_PART}(\.#{IPv4_PART}){3} )                        # or IPv4
    (:\d{1,5})?                                                  # optional port
    ([/?]\S*)?                                                   # optional /whatever or ?whatever
  DEFAULT_MESSAGE     = 'does not appear to be a valid URL'
  DEFAULT_MESSAGE_URL = 'does not appear to be valid'
  def validates_url_format_of(*attr_names)
    options = { :allow_nil => false,
                :allow_blank => false,
                :with => REGEXP }
    options = options.merge(attr_names.pop) if attr_names.last.is_a?(Hash)
    attr_names.each do |attr_name|
      message = attr_name.to_s.match(/(_|\b)URL(_|\b)/i) ? DEFAULT_MESSAGE_URL : DEFAULT_MESSAGE
      validates_format_of(attr_name, { :message => message }.merge(options))

Then my model extends that module:

class Location
  include Mongoid::Document
  include Mongoid::Timestamps
  extend ValidatesUrlFormatOf
  validates_url_format_of :url, :allow_blank => true

Testing HTTP basic authentication with RSpec 2

Posted by – July 6, 2010

Here's how I test my admin controllers that use HTTP basic authentication using RSpec 2:

before(:each) do
    user = 'test'
    pw = 'test_pw'
    request.env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Basic.encode_credentials(user,pw)

Actually, that's how I did it when I first tested things, but I've since put it in its own module under spec/support/auth_helper:

module AuthHelper
  # do admin login
  def admin_login
    user = 'test'
    pw = 'test_pw'
    request.env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Basic.encode_credentials(user,pw)

and now my controller spec looks like this:

describe Admin::LocationsController do
  include AuthHelper
  before(:each) do
  describe "GET index" do
    it "assigns all locations as @locations" do
      loc = Factory.create(:location)
      get :index
      assigns(:locations).should eq([loc])
  describe "GET show" do
    it "assigns the requested location as @location" do
      loc = Factory.create(:location)
      get :show, :id =>
      assigns(:location).should === loc

That "Factory" line comes from my use of factory_girl rather than fixtures.

Rails 3, RSpec, Mongoid and Database Cleaner

Posted by – July 5, 2010

After wrestling with various combinations of cleaning out my database between tests, this is what I'm using on a new Rails 3 application that uses Mongoid, RSpec 2, and Database Cleaner. I have one table (neighborhoods) which is populated using rake db:seed, so I'm excluding that from the cleanup.

Put this into your spec/spec_helper.rb:

require 'database_cleaner'
RSpec.configure do |config|
  config.mock_with :rspec
  config.before(:each) do
    DatabaseCleaner.orm = "mongoid" 
    DatabaseCleaner.strategy = :truncation, {:except => %w[ neighborhoods ]}

UPDATE: This isn't working for me now. Apparently the config.before(:each) part isn't being called in the versions of rspec (2.0.0.beta.21), cucumber (0.8.5), and cucumber-rails (0.3.2) that I'm using now. I'm now using the approach by Kevin Faustino here.

Quick fix for moving to Vlad the Deployer 2.0.0 with git

Posted by – September 9, 2009

I just upgraded my dev machine to version 2.0.0 of Vlad the Deployer. I got one unexpected error -- "Please specify the deploy path via the :deploy_to variable" -- but here is how I fixed it:

git support is now a separate gem, so remember to run

sudo gem install vlad-git

I also had some problems when version 1.4.0 was also on my machine, so I uninstalled that one with:

sudo gem uninstall vlad -v "1.4.0"

Using Amazon’s CloudFront with Rails & Paperclip

Posted by – September 8, 2009

It took me a bit of experimentation, and I never found an example in a single place that showed how to set it up exactly how I wanted, so here is my code in my model for storing images used by the ArtCat calendar on Amazon S3. I am using Paperclip version 2.3.1.

First you will need to set up the distribution in Amazon for your given bucket, so that you have a URL to use for the :s3_host_alist value. I also set up a CNAME so that I can use a nice url like

Note that I don't want to store any images other than my resized ones, so my :default_style is set to :original. Some of these values are actually constants in my config files, but I've replaced those here to make it more clear.

    has_attached_file :image,
      :storage => 's3',
      :s3_credentials => "#{RAILS_ROOT}/config/s3_credentials.yml",
      :bucket => 'artcal-production',
      :s3_host_alias => '',
      :url => ':s3_alias_url',
      :path => "images/:class/:id_:timestamp.:style.:extension",
      :styles => { :thumb  => '60x60#', :medium => '270x200#', :original  => '600x600>' },
      :default_style => :original,
      :default_url => '',
      :s3_headers => { 'Expires' => 1.year.from_now.httpdate },
      :convert_options => { :all => '-strip -trim' }

Note that you do NOT have to set the ActionController::Base.asset_host to your CNAME for images. Paperclip just handles it as expected for these images.

You'll notice an interpolation in the :path that is not standard. Thanks to this Intridea Company Blog post I learned that I will need to change my image names when they are updated. CloudFront will not update my image due to that Expires header I set above for a whole year, which is not what we want to happen. I solved this by including the timestamp based on the updated_at value for the image. Based on that Intridea post, this is the code I added to config/initalizers/paperclib.rb.

Paperclip.interpolates(:timestamp) do |attachment, style|

At first I was storing the images on the file system and serving them via Apache. Moving them to CloudFront improved my page load times by at least 50%, and means that I don't have to run as powerful as server to handle a lot of traffic on this image-heavy site as I might otherwise need.