CSS Asset Tagger Rails Plugin
December 3rd, 2009
We’ve released a new plugin for Rails that adds asset timestamps to assets found in an apps stylesheets.
The plugin is available at http://github.com/redlinesoftware/css_asset_tagger
Simply install the plugin and it will tag any assets in your css files with asset timestamps. More information on asset timestamps can be found at http://api.rubyonrails.org/classes/ActionView/Helpers/AssetTagHelper.html
We wrote a previous article on using asset timestamps with nginx, but similar usage applies to Apache as well for example.
The main purpose for writing this plugin is that stylesheets that use images for various things don’t get tagged with the asset timestamps when they’re written as plain old css files. These images can’t make use of expiration techniques very easily without the timestamps. So to make things work as they do with images in rails views, this plugin will add the same timestamps to assets in css files as they are in rails views.
Before…
#navigation_bar {
background-image: url(/images/background-nav.png);
}
After…
#navigation_bar {
background-image: url(/images/background-nav.png?1234567890);
}
If you’re using yslow and some decent expiration on the server and you don’t like seeing images from your css files being shown in your report card, this plugin should make those all go away and hopefully give you a better grade. :)
Silencing DB messages during tests
June 21st, 2009
When running tests in Rails, sometimes you need to perform various tasks in the database directly which can lead to a lot of unwanted messages in your test output.
If you’re using Postgresql, simply add the following line to your tests/tests_helper.rb file.
ActiveRecord::Base.connection.execute "set client_min_messages to ERROR"
Now you’ll only see messages of ERROR and above in your test output.
Update
Found a better way to do this. In your database.yml file, simply add the following line to your :test section.
min_messages: ERROR
Extending Named Scopes
February 14th, 2009
Quick code tip…
I’m using named_scope with a lambda as the 2nd paramater, but I also want to extend the named_scope with some custom methods.
named_scope :for_league, lambda{|league_id| {league conditions} } do
def default
end
def do_something_custom
end
end
I use the same extended methods in more than one place, so I figured I’d use something similar to the :extend option used with association methods like has_many, but I can’t pass an :extend option if I’m also using a lambda.
The way around this is to just include the methods directly in the block.
module Associations
def default
end
def do_something_custom
end
end
named_scope :for_league, lambda{|league_id| {league conditions} } do
include Associations
end
Works like a charm. Now I can just reuse the Associations module where I need it.
Nginx expiry for Ruby on Rails
January 25th, 2009
Setting the expiry header is a pretty easy way to optimize page loads. Rails helps with this by adding a 10 digit query string that represents the last modified time of the file to assets such as images, stylesheets and javascript files .
Some details on the asset timestamp (the query string of the url) can be viewed in the rails api docs in the Using asset timestamps section.
An example of the paths generated in your views look like this…
/stylesheets/styles.css?1234567890
So if you’re using Nginx, how do we configure things to properly set the expires header?
Read the rest of this entryfile_column image regeneration
August 11th, 2008
If you use file_column for some projects and find that you want to change the thumbnail sizes that you’ve been using for models, then hopefully this little bit of code can help.
Add this as a rake task and run it as rake "filecolumn:regenerate[Model, field]" RAILS_ENV=production where Model is the model you want to regenerate images for and field is the filecolumn field on the model. The task uses Rake arguments, so you’ll need Rake 0.8.
namespace :filecolumn do
desc "Regenerate filecolumn images"
task :regenerate, :model, :field, :needs => :environment do |task,args|
if args.any?{|k,v| v.blank?}
puts "Usage: #{task.name}[Model,field]"
else
klass, field = args.model.constantize, args.field
klass.all.each do |obj|
puts "Regenerating #{klass} #{obj.id}"
next if obj.send(field).nil?
state = obj.send("#{field}_state")
state.instance_variable_set(:@just_uploaded, true)
state.transform_with_magick
end
end
end
end
The code essentially boils down to 2 lines…
- setting @just_uploaded to true on the state object
- calling the transform_with_magick method on the state object
Using God to automatically monitor mongrels
April 4th, 2008
Having a process that automatically monitors your system and restarts applications when things get out of wack is pretty important to have. The 2 popular free options are God and Monit. This article is about not only setting up God to monitor your mongrels, but setting up God only ONCE to do this. If you add another mongrel cluster to your system, all you have to do is restart God.
Read the rest of this entryLooking for Mephisto 0.8?
March 26th, 2008
I was too, so I popped into the #mephisto channel on freenode and technoweenie set me straight. The subversion trunk in mephisto will be the latest stable release (in this case 0.8) of his github repo.
But for an easy way to just download the 0.8 release, go here and then click on download and you’ll get a nice shiny tarball.
Thanks to the Mepisto team for making a great blogging app!
will_paginate and remote AJAX links
January 30th, 2008
Updated for will_paginate 2.3.x
So you’re using the will_paginate plugin and want to use remote AJAX links. You’re not using the will_paginate plugin? Simply install it with…
script/plugin install git://github.com/mislav/will_paginate.git
or install the gem and specify it in your config/environment.rb file
sudo gem install mislav-will_paginate
config.gem 'mislav-will_paginate', :lib => 'will_paginate', :source => 'http://gems.github.com'
will_paginate is an alternative to the classic_pagination plugin, which is the pagination plugin that basically took the pre Rails 2.0 pagination implementation and packaged it in plugin form. I won’t discuss the differences between the two plugins here, but there’s a good video explaining the two from Railscasts here.
Out of the box, will_paginate doesn’t allow remote AJAX links for page links, so I’ll show you an easy way to add such functionality…
Read the rest of this entryCustom rails app config options
January 5th, 2008
Do you use RAILS_ENV in your Rails app to execute different code depending on the environment you’re running?
if RAILS_ENV == 'development'
log_some_data_or_do_something_different
else
go_with_the_flow
end
No? Ok, great. Yes? Ok, not so great.
Those from both camps are likely to get something out of this post, so read on.
Read the rest of this entryHuman Attribute Override Plugin Tutorial
January 1st, 2008
This is my second tutorial covering the plugins that we’ve developed.
This tutorial covers the human attribute override plugin.
The plugin allows humanized versions of attributes to be overridden with custom strings to provide a better conversion than human_name may provide.
Why?
The main reason for creating this plugin is that Rails doesn’t always provide an acceptable “humanized” version of an attribute name.
Column.new('num_employees', ...).human_name # => 'Num employees'
You could argue that perhaps the attribute should be named number_of_employees..
Column.new('number_of_employees', ...).human_name # => 'Number of employees'
But this is hardly an acceptable solution for various reasons
- The attribute name is too wordy.
- Changing an attribute name for the sake of it’s humanized version reading better results in unneeded refactoring.
- You’re using a legacy database that uses a specific naming convention.
Tip: DB views as ActiveRecord models
January 1st, 2008
Here’s a quick tip for anybody using a database view as an ActiveRecord model…
If you want to use your view as a model and take advantage of the association methods properly (like belongs_to, etc.), you must make sure that your view specifies a unique column that can be used as the primary key. Without a primary key for the view, you’ll likely run into some nasty bugs down the road (mine occurred when I tried to use eager loading via :include with the “view model”).
First off, to use the view as a model, you don’t need to do anything different than what you’d do for a regular table.
class ViewModel < ActiveRecord::Base
end
Here are some ways to set your primary key for your view model:
1) If your view already has a unique “id” field, then you’re done. No need to do anything else.
2) If your view has a unique field, but it’s not called “id”, simply use the set_primary_key method.class ViewModel < ActiveRecord::Base
set_primary_key :unique_id # unique_id will be the name of a unique column used in the view
end
3) Create a new field in the view that can be used as the primary key.
create view view_model as select (field1_id::varchar + '-' + field2_id::varchar) as id, ...
The above SQL example uses two fields combined into one to form a unique field called “id” and this will be picked up automatically by ActiveRecord. The reason for adding the ’-’ separator is so that 2 combinations of 2 separate values don’t combine to form the same value.
With no separator: field1_id = 10, field2_id = 10, id = 1010 and field1_id = 101, field2_id = 0, id = 1010
versus
With a separator: field1_id = 10, field2_id = 10, id = 10-10 and field1_id = 101, field2_id = 0, id = 101-0
To those who know their databases, you’ll recognize this as basically a composite key and since RoR doesn’t support composite keys out of the box, this can be used to mimic one.
4) Use a composite key plugin like http://compositekeys.rubyforge.org to add composite key support to RoR
Now you can use composite keys instead of the method of generating one as in item 3.
class ViewModel < ActiveRecord::Base
set_primary_keys :field1_id, :field2_id
end
note Pretty much everything here applies to a regular model based off a table, but when creating a view, it’s more common to not include a column that will be unique for each record like the “id” field used in almost all tables used with RoR.
Conditional Cache Plugin Tutorial
November 26th, 2007
Update
This plugin has now been DEPRECATED for Rails 2.2+ in favour of the built in :if and :cache_path options.
The following changes can be made to use :cache_path instead of the :tag option.
- Change all instances of :tag to :cache_path
- If the :tag referred to a sybmol such as
:tag => :standard_tag, you simply need to change the method name that the symbol refers to asstandard_tag_url(just add _url to the end of the method name). - The host name no longer prefixes the cache fragment when :cache_path uses anything other than a hash, so make sure to begin your cache_path with the string generated from
request.url(includes protocol) orrequest.host + request.request_uri(no protocol) if your cache fragment keys depend on the host name.
Updated for Rails 2.1
This is my first of many tutorials to come covering the plugins that we’ve developed.
This tutorial covers the conditional cache plugin, which is actually the first plugin released by Redline.
Why?
By default, the caches_action method allows you to specify one or more actions to apply caching to.
class TestController < ApplicationController
caches_action :index, :new
def index
...
end
def new
...
end
end
In the above example, action caching is being applied to the index and new action. Beyond that we have no additional control over when these actions should be cached or how these actions should be cached. It’s either all or nothing.
So to fix this “all or nothing” problem, the conditional cache plugin adds additonal functionality to the caches_action method by adding 2 additional parameter options that can be passed to the method along with the existing list of actions.
Read the rest of this entrySelection javascript lib
October 26th, 2007
I’ve created a basic first draft for a javascript selection library. The library allows the user to select many elements on a web page with a simple mouse drag.
I call this version 0.1 as it has only been tested in Firefox and has some minor issues that need some cleaning up, but I figured I might as well make it public so people can take a look, try it, give feedback, or send patches.
You can grab the files and see a demo of it here
The library requires prototype and builder… both of which come with Rails.
Patches and feedback are welcome.
Conditional Cache updates
October 25th, 2007
I’ve recently fixed a bug in our conditional cache plugin that I introduced while making it compatible with Rails 1.2.4.
The bug has been fixed and the plugin also works with Rails 1.2.5.
The bug was causing the wrong cache paths to be created, so if you updated the plugin, update again ASAP.
Conditional Cache plugin now compatible with Rails 1.2.4
October 12th, 2007
The conditional cache plugin has been updated to be compatible with Rails 1.2.4. If you’re still using a previous version of Rails, there is no need to upgrade the plugin.
Update: Compatible with Rails 1.2.5 now
