Cucumber testing and ssl

Problem

Your application is ussing force_ssl to redirect all calls to ‘https’, but when you try to use your cucumber tests they fail.

Solution

By using the suggestion here, you can add a file in your initializers to bypass the ssl in development and test environment as follows:

module ActionController
  module ForceSSL
    module ClassMethods
      def force_ssl(options = {})
        before_filter(options) do
          if !request.ssl? && !Rails.env.development? && !Rails.env.test?
            redirect_to :protocol => 'https://', :status => :moved_permanently
          end
        end
      end
    end
  end
end

deploy:assets:precompile insists on running on production environment in capistrano

Problem
You want to deploy your rails 3.2 application to another environment except production, but the default capistrano recipe for precompiling the assets keeps using the production environment as in:

 * executing `deploy:assets:precompile'
  * executing "cd /var/www/dev/app/releases/20120816130649 && rake RAILS_ENV=production RAILS_GROUPS=assets assets:precompile"
    servers: ["server.name.com"]

Solution
Add the following environment option in your deploy/other_env.rb file:

set :rails_env, "other_env"

Creating a user token with Devise for other uses except log in into the system

Problem

You are using Devise in your rails application, and you want to have a token for authenticating an API call, but you don’t want to use the default authentication token so that.
The purpose of doing something like that is that you don’t want the application to have the same authentication rights as the devise authentication tokens.

Solution

Add the field to your user model (ie app_token).

On your user model create the following:

class User < ActiveRecord::Base

before_create :create_app_token
...
private
def create_app_token
  self.app_token = Devise.friendly_token
end

Error in staging environment with tr8n and will_filter

Problem
You are using the tr8n translation engine, which works fine in your local development environment, and you want to use it in an environment called ‘staging’, but after deployment you get the following error in your log files;

NoMethodError (undefined method `[]' for nil:NilClass):                                                                                                                                                                                       
  will_filter (3.1.9) lib/will_filter/config.rb:92:in `user_filters_enabled?'                                                                                                                                                                 
  will_filter (3.1.9) lib/will_filter/extensions/action_controller_extension.rb:34:in `init_will_filter'

Solution

The default configuration file for will_filter includes an environment called ‘stage’ and not ‘staging’.
So you can add the following into the config/will_filter/config.yml file in your application (just afer the stage: line):

staging:
  <<: *defaults

SSL testing in rspec

Problem
You have added the force_ssl option in your rails application, and the rspec tests fail with a redirection as ssl is required in the test evnironment.

Solution
Using a solution provided here you can add the following to your rspec test to ensure that ssl is used and the tests pass:

before(:each) do
  request.env["rack.url_scheme"] = "https"
end

Apache rewrite rule to redirect https to http for pages you don’t need https

Problem

You are using your Rails 3.2.x application with Apache and you have setup force_ssl in one of your controllers (ie payments), that you want to force the application to use ssl. But after you set it up, and you go to one of the actions for that controller, every subsequent page you follow still uses the https protocol, even if you don’t want them to.
So you need a way to force the serving of pages in http.

Solution

You can use a redirection in your SSL apache conf file, and specify that when it doesn’t match the sections (controller,actions) you specify it should be redirected to http.
Note that RewriteCond in Apache are by default ANDed when they are in subsequent lines so you can add more conditions and that you can use [OR] if you want to perform an OR logic operation.
So by adding the following in your virtual host for the 443 port (ssl), and apply the changes it should be working as expected:

# Add https to http redirection
RewriteCond %{HTTPS} on
RewriteCond %{REQUEST_URI} !^/controller_you_want_ssl.*
RewriteRule (.*)  http://%{HTTP_HOST}%{REQUEST_URI}

Capistrano recipe to restart standalone passenger server

Problem
You want to be able to use different ruby versions with passenger and by following the article here, you have set up your server to server the second version with a standalone passenger version. If you do that you cannot use the ‘touch tmp/restart.txt’ command to restart the standalone passenger server.

Solution
What you would need to do in your config/deploy.rb file, and assuming that your standalone passenger runs on a port (4000) different from the default (3000), is to replace the following:

run "#{try_sudo} touch #{File.join(current_path,'tmp','restart.txt')}"

with

run "cd #{release_path} && passenger stop -p 4000 && passenger start #{current_path} -a 127.0.0.1 -p 4000 -e production -d --pid-file #{current_path}/tmp/pids/passenger.4000.pid --log-file #{current_path}/log/passenger.4000.log"

Javascript file not compiled in production with Rails asset pipeline

Problem

You have updated your application to the new 3.1.x or 3.2.x rails, and you are using the new asset pipeline.
You have a javascript file (example.js) that is only called in a specific view or conditionally (especially for css).
The application works fine in the development environment but when deploying in the production (or staging) server, you get an error like the following in the log file:

ActionView::Template::Error (example.js isn't precompiled)

Solution

As the new asset pipeline puts everything together in one file, your file that is called from a different place cannot be found.
Even if you include your example.js in the application.js manifest file with a //= require example, you still get the same error.
It is possible to compile a single javascript file separately from all the other ones.
So what you have to do is include the following into your necessary environment file (staging.rb, production.rb etc), or in the application.rb file if it going to be used in more than one environments.

config.assets.precompile += ['example.js']

Make sure that you include the .js in the code above, and then redeploy with capistrano cap staging|production deploy.