Rajan Agaskar's blog



Rajan AgaskarRajan Agaskar
Standup 10/31/08
edit Posted by Rajan Agaskar on Friday October 31, 2008 at 04:27PM

Interesting Things

  • Aliasing ActiveRecord reader methods

    ActiveRecord reader methods are not eagerly loaded, and as such cannot be aliased using alias_method. There are a number of workarounds to this, those talked about included: calling self.define_read_methods, after which all your read methods will be loaded and available for aliasing, or you can simply define the alias instead of using alias_method.

  • belongs_to and foreign keys.

    If you specify an alternate foreign key when using belongs to, you will have access to that id via the name of the foreign key, and not the name of the belongs_to association. It may be worthwhile allowing access to the id via the belongs_to association in order to keep consistency.

  • boo

    BOOOO!!!!! BOOOOOOOOO!

Rajan AgaskarRajan Agaskar
Standup 10/30/08
edit Posted by Rajan Agaskar on Thursday October 30, 2008 at 04:17PM

Interesting Things

  • Removing class definitions with Object.send(:remove_const, :Foo)

Sometimes it is necessary to reload or replace a stub/test class during testing (apparently rspec is particularly susceptible to this). This can be achieved using Object.send(:remove_const, :Foo) where Foo is the camel-cased name of the class. If your class is defined within a module, it may be necessary to use Module.send(:remove_const, :Foo)

Ask for help

  • foo.bar.reload versus foo.bar(true)

As a point of curiosity, does anybody know when has_many relationship reloading moved from (or to?) foo.bar(true) to foo.bar.reload? The reload syntax seems preferable for readability; will foo.bar(true) continue to work in the future?

Rajan AgaskarRajan Agaskar
Standup 10/29/08
edit Posted by Rajan Agaskar on Wednesday October 29, 2008 at 04:28PM

Interesting Things

  • has_many_polymorphs preloads models

has_many_polymorphs will scan through the models directory for any files that include the plugin and preload them. This can cause problems if these models depend on other plugins (that have not yet been loaded) to operate correctly. The has_many_polymorphs source mentions this behavior in a comment and includes a fix:

Searches for models that use has_many_polymorphs or acts_as_double_polymorphic_join and makes sure that they get loaded during app initialization. This ensures that helper methods are injected into the target classes. Note that you can override DEFAULT_OPTIONS via Rails::Configuration#has_many_polymorphs_options. For example, if you need an application extension to be required before has_many_polymorphs loads your models, add an after_initialize block in config/environment.rb that appends to the 'requirements' key:
  Rails::Initializer.run do |config|     
    # your other configuration here

    config.after_initialize do
      config.has_many_polymorphs_options['requirements'] << 'lib/my_extension'
    end    
  end

Instead of using config.has_many_polymorphs_options, we were able to achieve the same effect by simply dropping our required plugins into the after_initialize block. If we decide to remove has_many_polymorphs in the future, the config file should still run correctly. It's worth noting that the UltraSphinx search plugin operates in a similar fashion.

  • returning JavaScript in an Ajax IFrame Method (AIM) call

If you are using AIM for file uploads, you may find that any content returned to the IFrame is escaped (as if it were regular HTML). On some browsers, this occurs regardless of what the content-type is set to. A workaround is to embed any content that you don't want escaped into a comment tag; after the request completes, you can use JavaScript to retrieve the contents and optionally eval them.

Ask for help

  • Ajax click_and_wait for Selenium?

assert_text_present offers a simple way to test Ajax behaviors in Selenium, as it will wait 5 seconds (during which the Ajax callback can complete) while looking for the specified text (which can be the body of your Ajax response). Another strategy with which we've had some luck is to write a custom method that will wait a specified amount of time before continuing (particularly useful if your Ajax call takes a lengthy amount of time to complete).

Rajan AgaskarRajan Agaskar
Standup 10/28/08
edit Posted by Rajan Agaskar on Tuesday October 28, 2008 at 04:44PM

Interesting Things

  • before_save and after_save may not perform as you expect!

Previously, returning false from before or after filters callbacks would halt the chain entirely. This is no longer the case, except with before_save and after_save -- returning false in a before_save will stop the filter callback chain and prevent a save, returning false in an after_save will stop the filter chain silently, and NOT rollback the save. This can be troublesome if you have after_save filters callbacks you expect to execute, especially if you have conditional clauses in an after_save, as they can easily return a false value where you did not intend it.

Please see Brandon Keepers' clarification regarding filters vs. callbacks below -- thanks Brandon!

Ask for help

  • Bootstrapping data into an existing system?

Using migrations for one-time data inserts can be problematic (for example, when changing seed data; additionally, it's advisable to create a database from the schema.rb rather than migrations) , it can be useful to create a class that is responsible for inserting the seed data into the database. This class can be wrapped in a capistrano or rake task. The db-populate plugin is designed to aid in this task.

  • Multiple Routes/One controller

It is possible to point multiple routes at a single controller, however, this situation may suggest a need for multiple controllers, possibly inheriting from a single base controller containing any shared logic. This prevents a excessive switching logic in controllers, which can help minimize the possibility of argument-related bugs.