Using localized_country_select with air_budd_form_builder in Ruby on Rails

For my current project instead of rolling out my own form builder I went for the github’s air_budd_form_builder. It generates nice, semantic HTML code. This project also required localized_country_select, so in order to make these plugins compatible I had to prepare this little snippet:

module AirBlade
  module AirBudd
    class FormBuilder
      def input_type_for(field_helper)
        case field_helper
        when 'text_field';     'text'
        when 'text_area';      'text'
        when 'password_field'; 'password'
        when 'file_field';     'file'
        when 'hidden_field';   'hidden'
        when 'check_box';      'checkbox'
        when 'radio_button';   'radio'
        when 'select';         'select'
        when 'date_select';    'select'
        when 'time_select';    'select'
        when 'country_select'; 'select'
        when 'localized_country_select'; 'select'
        else ''
        end
      end
    end
  end
end

module AirBlade
  module AirBudd
    class FormBuilder
      %w( localized_country_select ).each do |name|
        create_collection_field_helper name
      end
    end
  end
end

Put it in your application’s lib directory and enjoy!

Reseting ExtJS 2.1 GridView column sorting

Reseting ExtJS's GridView column sorting can be a bit tricky - the API doesn’t provide any way to do this. So we have to cook our own way.

To reset sorting state first we need to extend the Ext.grid.GridView class:

Ext.override(Ext.grid.GridView,
{
    // private
    _resetSortState: false,

    resetSortState: function()
    {
        this._resetSortState = true;
    },

    updateHeaderSortState: function()
    {
        if (this._resetSortState === true)
        {
            this._resetSortState = false;

            delete this.ds.baseParams['dir'];
            delete this.ds.baseParams['sort'];
            delete this.sortState;
            this.mainHd.select('td').removeClass(this.sortClasses);
            this.grid.fireEvent('sortchange', this.grid, null);
        }
        else
        {
            // ExtJS updateHeaderSortState function
            var state = this.ds.getSortState();
            if(!state){
                return;
            }
            if(!this.sortState || (this.sortState.field != state.field || this.sortState.direction != state.direction)){
                this.grid.fireEvent('sortchange', this.grid, state);
            }
            this.sortState = state;
            var sortColumn = this.cm.findColumnIndex(state.field);
            if(sortColumn != -1){
                var sortDir = state.direction;
                this.updateSortIcon(sortColumn, sortDir);
            }
        }
    }
});

Include this snippet in your application. How to use it? I hooked it to my Ext.Toolbar.Button handler:

new Ext.Toolbar.Button(
{
	text: 'My Toolbar Button',
	handler: function()
	{
		myGrid.view.resetSortState();
		myStore.removeAll();
		myStore.load({params : {start : 0}});
	},
	scope: this
}));

That’s it! This code has been tested with ExtJS 2.1.

Generating Ruby on Rails UTC-based migrations with TextMate

TextMate is a great tool for all Mac-based Ruby on Rails developers, but even if you’re using the Cutting-Edge updates you’re most likely still stuck with the old migrations generator.

Here’s a quick fix if you want to use UTC-based migrations (introduced in Rails 2.1). From your favourite Terminal application launch:

mate /Applications/TextMate.app/Contents/SharedSupport/Bundles/Ruby\ on\ Rails.tmbundle/Support/bin/generate_quick_migration.rb

Then just comment (or delete) the following code:

files = Dir.glob(File.join(migration_dir, "[0-9][0-9][0-9]_*"))
if files.empty?
  number = "001"
else
  number = File.basename(files[-1])[0..2].succ
end

And replace it with:

number = Time.now.utc.strftime("%Y%m%d%H%M%S")

There’s just one glitch with this solution - it’ll probably be overwritten whenever you update your Textmate application. However, this doesn’t happen very often, does it? If you have a better solution - let me know in the comments, I’m a TextMate beginner, so bear with me!