Monit and Phusion Passenger

April 30th, 2011 No Comments »

While there’re multiple tools available for monitoring, ranging from Dan Bernshtein’s daemontools to God, I found that Monit is a pretty balanced solution. On one hand, it’s quite powerful, and on the other – it’s not resource hungry. The only drawback that I found, is that for monitoring a process, the process must have a pid-file saved somewhere. The Monit FAQ states that the programs which don’t have pid-file support should be run with some wrapper which will create it on their behalf.

I wanted to use Monit to monitor Rails’ instances, so if they grow too fat, Monit will take care of that. The problem is that the pid file that the Passenger creates a) doesn’t have a predictable location (there’s something called “generation” or something like that), and b) doesn’t have children, as those processes are detached.

Of course there exists a possibility of patching Passenger for providing such pid files. But, luckily, Passenger provides extension points in form of callbacks which are fired when the application instance is created and when it’s taken down.

It was trivial to use this API to provide pid-file managing. The result of this work was the “passenger_monit” plugin.

So, go ahead, add ‘gem “passenger_monit”‘ to your Gemfile and give it a try!

The source is available from:
https://github.com/romanbsd/passenger_monit

April 5th, 2011 No Comments »

Logging line numbers in Ruby Logger can be done with a simple decorator:

  class LoggerDecorator
    def initialize(logger)
      @logger = logger
    end
 
    %w{debug info warn error fatal}.each do |method|
      eval(<<-eomethod)
        def #{method}(msg)
          @logger.#{method}(position) {msg}
        end
      eomethod
    end
 
    private
    def position
      caller.at(1).sub(%r{.*/},'').sub(%r{:in\s.*},'')
    end
  end

ExtJS with Rails 3

March 6th, 2011 3 Comments »

In order to make ExtJS play nicely with Rails, the following tweaks are needed:

On the ExtJS javascript side, the following things are needed:

1. Ask server to server JSON:

Ext.Ajax.defaultHeaders = {'Accept': 'application/json'};

2. RailsJsonStore:

Ext.data.RailsJsonStore = Ext.extend(Ext.data.JsonStore, {
    constructor: function(config) {
        Ext.data.RailsJsonStore.superclass.constructor.call(this, Ext.applyIf(config, {
            messageProperty: 'message', //for store.reader.getMessage()
            restful: true,
            url: '/'+ config['root'] + 's',
            writer: {encode: false}
        }));
    }
});
Ext.reg('railsjsonstore', Ext.data.RailsJsonStore);

3. XSRF protection:

Ext.Ajax.on('beforerequest', function(o) {
        var csrf = Ext.select("meta[name='csrf-token']").first();
        if (csrf) {
                o.defaultHeaders = Ext.apply(o.defaultHeaders || {}, {'X-CSRF-Token': csrf.getAttribute('content')});
        }
});

On Rails side:

config.active_record.include_root_in_json = false

I18n support for validates_date_time

February 8th, 2009 2 Comments »

This simple fix uses the fact, that if the second argument to the ‘add’ method is a symbol, then a generate_message is called, which does all the voodoo of Rails 2.2 I18n.
I tried to contact the original author to no avail, therefore I’ll post it here, hoping that if anyone needs it, it’ll surface on a Google search.
The fix itself is quite simple:

Index: lib/validates_date_time.rb
===================================================================
--- lib/validates_date_time.rb  (revision 403)
+++ lib/validates_date_time.rb  (working copy)
@@ -114,7 +114,7 @@
       if options[:before]
         options[:before].each do |r|
           if r.value(record) and value >= r.last_value
-            record.errors.add(attr_name, options[:before_message] % r)
+            record.errors.add(attr_name, :before, :default => options[:before_message] % r)
             break
           end
         end
@@ -123,7 +123,7 @@
       if options[:after]
         options[:after].each do |r|
           if r.value(record) and value <= r.last_value
-            record.errors.add(attr_name, options[:after_message] % r)
+            record.errors.add(attr_name, :after, :default => options[:after_message] % r)
             break
           end
         end

I’ve a fork of the git-svn mirror here:
http://github.com/romanbsd/validates_date_time/tree/master

Then, for using it, you’ll just need to have the following path in your locale yml files (for example):

  activerecord:
    errors:
      models:
        user:
          attributes:
            birth_date:
              before: 'is wrong'
              after: 'is wrong'

Displaying recaptcha inside ModalBox

January 30th, 2009 1 Comment »

I just wanted to display reCAPTCHA inside a ModalBox.
This simple task turned out to be quite complicated.
After playing with innerHTML, creating