Total results: 17

An IE8 background-size fallback with SCSS or SASS

In this post I will show you how to get the background-size CSS property working in IE 6 - 8 without using JavaScript. Instead we will use the filter attribute recognised by older versions of Internet Explorer.

Background

As you can see on Can I Use, IE 6 - 8 are the only browsers not supporting background-size at all.

Microsoft does however offer a AlphaImageLoader filter with sizingMethod options that correlate to the CSS3 background-size options.

  • auto = image
  • cover = scale
  • contain = crop

(CSS3 on left, sizingMethod on right)

The Solution

We will write a mixin that applies the filter rule for us. In this example I will use SCSS syntax and implement a fix for background-size: cover, as this is the most common use case.

If you want to convert this to SASS, please check out SASS to SCSS.

The mixin looks as follows:

@mixin background-cover($image-path) {
  background-size: cover;
  background-image: url(#{$image-path});
  filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='#{$image-path}', sizingMethod='scale');
  -ms-filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='#{$image-path}', sizingMethod='scale')";
}

This mixin accepts an argument that is the path to the image. So it could be used for example like so:

.foo {
  @include background-cover('images/bar.jpg');
  background-color: #fff;
  background-position: right bottom;
}

A great advantage of this approach is that if you are using Ruby on Rails and need to include the asset pipeline paths in your CSS, you can use the standard asset-path helper wrapped around the argument.

.foo {
  @include background-cover(asset-path('bar.jpg'));
  ...
}

Conclusion

You may want to note that Internet Explorer filters are not valid CSS, so if you are an advocate of purely valid CSS, you may want to use a JavaScript polyfill or isolate this code in a separate stylesheet.

In general though, I think this is a great solution when older IE support is required. No JavaScript or CSS plugins are necessary and the method can easily be dropped into a SASS/SCSS project.

The solution could also easily be adapted for preprocessors such as LESS.js, or even pure CSS with little effort.

Please let me know if you find any other short solutions to this problem, I'd love to hear about other options.

Sidekiq tasks for Capistrano 3

If using the Sidekiq gem with Capistrano version 3, you may like a simple set of start, stop and restart tasks. There are a few gems out there already built to help you with this, which might be suitable for your project. If you however just want a simple script then you may use this sidekiq namespace I wrote and tweak it to your needs.

Place the following in your deploy.rb

namespace :sidekiq do
  def sidekiq_pid
    current_path + '../shared/pids/sidekiq.pid'
  end

  def pid_file_exists?
    test(*("[ -f #{sidekiq_pid} ]").split(' '))
  end

  def pid_process_exists?
    pid_file_exists? and test(*("kill -0 $( cat #{sidekiq_pid} )").split(' '))
  end

  task :start do
    on roles(:app) do
      if !pid_process_exists?
        execute "cd #{current_path} && RAILS_ENV=#{fetch(:rails_env)} #{fetch(:rbenv_prefix)} bundle exec sidekiq -C config/sidekiq.yml -e #{fetch(:rails_env)} -L log/sidekiq.log -P #{sidekiq_pid} -d"
      end
    end
  end

  task :stop do
    on roles(:app) do
      if pid_process_exists?
        execute "kill `cat #{sidekiq_pid}`"
        execute "rm #{sidekiq_pid}"
      end
    end
  end

  task :restart do
    on roles(:app) do
      invoke "sidekiq:stop"
      invoke "sidekiq:start"
    end
  end
end

after 'deploy:restart', 'sidekiq:start'

Convert all ERB templates to HAML across project

If you have a Ruby on Rails project and would like to convert all .erb templates to .haml across the project, you can follow these simple steps that will result in all .erb's files being parsed to new valid HAML and then the old ERB templates are deleted, in 3 simple steps.

1. Prerequisites

Install the following gems haml, hpricot, ruby_parser and html2haml. You do not necessarily need to have these in your Gemfile, just available on the system. Install in the following order:

gem install haml hpricot ruby_parser html2haml

2. Create new HAML files

Use the following bash script that will find all .erb files and then pipes them to Ruby so that it can run the html2haml command on each one.

To test what files will be generated without making changes:

find . -name '*erb' | xargs ruby -e 'ARGV.each { |i| puts "html2haml -r #{i} #{i.sub(/erb$/,"haml")}"}'

If you are happy with the output, simply pipe the command back into bash to execute the changes:

find . -name '*erb' | xargs ruby -e 'ARGV.each { |i| puts "html2haml -r #{i} #{i.sub(/erb$/,"haml")}"}' | bash

3. Remove old ERB files

Run this similar bash snippet that finds all files with a .erb extension and deletes them:

find . -name '*erb' | xargs rm -rf ARGV

RubyMine: .ruby-version Gemset cannot be loaded

If you have installed RubyMine and the IDE complains that it cannot switch the Ruby SDK because the Ruby environment wasn't found based on your given .ruby-version file, try explicitly stating the ruby executable name.

This means simply change your .ruby-version from:

2.1.2

to:

ruby-2.1.2

Fixing the "You tried to define an association named transaction" Ruby on Rails Error

I recently encountered an error in Rails where I was trying to connect a Category model to a Transaction model. I had a has_one associtation and encountered the following error:

class Category < ActiveRecord::Base
  has_one :transaction
end

"You tried to define an association named transaction on the model Category, but this will conflict with a method transaction already defined by Active Record. Please choose a different association name."

This is caused by ActiveRecord already using a method named "transactions". To handle this issue, choose an appropriate alternative name for the association and specify the model class and foreign key manually.

has_one :association_name, :foreign_key: "key_name", class_name: "ModelClass"

In my case this was implement as:

class Category < ActiveRecord::Base
  #has_one :transaction
  has_one :owner, foreign_key: "category_id", class_name: "Transaction"
end

How to handle user time zones in Ruby on Rails

Displaying a date time correctly for users around the world is made very easy with Ruby on Rails. The time zone can be set per request and loaded from the logged in user's configuration. All of the default time zones are already built into Ruby on Rails and provides the ability to add custom ones, for custom cities too.

Model

First we need to allow the user to choose their desired timezone, so a migration is required:

class AddTimezoneToUser < ActiveRecord::Migration
  def change
    add_column :users, :timezone, :string
  end
end

Then of course this change needs to be applied to the database.

$ rake db:migrate

Then ensure the User model has timezone under its accessible attributes

class User < ActiveRecord::Base
    attr_accessible :email, :name, :timezone, :created_at, :updated_at
end

View

Next we must provide a field to choose from. In this example I am simply adding a new form field to my users/_form.html.erb partial. Here we use the built in time_zone_select form helper.


Which will automatically give a result similar to the following screenshot. The select menu is prefilled from the Rails ActiveSupport::TimeZone class.

image

Controller

Lastly, an application controller before_filter is required that will set the time zone for each request.

class ApplicationController < ActionController::Base
  protect_from_forgery
  before_filter :set_timezone

  private

  def set_timezone
    tz = current_user ? current_user.timezone : nil
    Time.zone = tz || ActiveSupport::TimeZone["London"]
  end
end

Here current_user points to the logged in user record. This is the default behavior when using the "devise" gem. If the current user does not have a timezone, I choose to fallback to GMT (London) time. This can be changed for whatever default makes sense in your given project.

The "ctrl + alt + delete" of RVM

When ever you are trying to install a Ruby, package or anything else with RVM it is not that uncommon to run into strange issues. Just like when you first go to smashing the Ctrl + Alt + Delete keys on Windows, I have found through experience that the first port of call should be to take the following simple steps.

For an example, imagine you are trying to install Ruby 1.9.2. I recently had to use this approach to get version 1.9.2 installed on OSX Lion.

Note: On OSX, Make sure you have either the GCC libraries or XCode 4.2+ installed to work best with RVM

Steps

  1. rvm get head
  2. rvm reload
  3. rvm remove 1.9.2
  4. rvm install 1.9.2

First we update RVM, reload the environment (important) remove whatever broken ruby/package you are trying to get working. Finally, Install it fresh. 

You would be suprised how often this resolves issues. Give it a try next time you are having issues.

Show git branch and directory in your shell

It's really handy to be able to see the current git branch in your shell prompt along with the directory name. This for a start removes many "git branch" commands from your history.

To enable this feature, you have to edit your .bashrc file on Linux or the .bash_profile on Mac. These files usually exist in your home directory (The default directory when you open a shell) and are executed when the shell logs in. You can edit this file with any text editor such as Gedit or Textmate.

Add the following 2 lines after any existing SP1 variables and then save your file. Open a new shell to see the changes.

GIT_PS1_SHOWDIRTYSTATE=false
export PS1='\[\033[1;36m\]\u at\[\033[00m\] \[\033[34m\]\W\[\033[31m\]$("__git_ps1")\[\033[00m\]  >  '


SP1 colour example

Changing colours

If you would like to update the colours of the prompt, then visit this article to get a grasp of the basics and you can find much more on Google from there.

© Blake Simpson, 2012 – 2019