bookmark_borderRailsConf Europe 2006

Marcel and DHH were very surprized to know that I had flown in from India for the RailsConf.

I enjoyed most of the sessions that I attended. With four tracks going on in parallel definitely I missed out on some very good ones.

  • DHH’s session on ActiveResource was great. He demoed what he had talked about at Chicago RailsConf. I have also moved one of my projects to the edge to start playing with simply_restful.
  • Marcel’s session on making RJS DRYer was also good. simply_helpful is a good way of doing this. It applies the same philosophy to the View side of things, that simply_restful applies to the controller. Using the simply_helpful plugin, the application can use a lot of meaningful default, hence making the views and helpers a lot more dry-er.
  • Jamis just released a new version of capistrano and he demoed the cool new features. The slickest of them was the cap shell. It is a great tool to monitor multiple serves in a cluster from a single console, with the ability to run commands against only particular machines in the cluster identified by roles that the machines play in the cluster.
  • Jim Weirich’s plenary session was great. He demonstrated a lot of common mistakes that programmers make, because of Ruby’s open classes. A lot of his talk featured around being good to other’s code.
  • Dave Thomas and Kathy Siera were outstanding, entertaining and passionate as usual!

bookmark_borderready for RailsConfEurope2006, PizzaonRails

I am Travelling to London this wednesday, to attend the first RailsConf Europe 2006

I will be attending the pre-conference social PizzaOnRails on Wednesday evening. Then the RailsConf on Thursday, Friday.
I will be visiting the Shinnyo-en temple in Surrey on Saturday morning and be back in Central London by the afternoon.
Am flying back to Delhi on Sunday morning.

Anybody interested in meeting up to discuss ruby, rails, buddhism, India whatever… drop me
a mail.

bookmark_borderalready initialized constant in fixtures

Following the dynamic fixture example from most of the rail’s books and tutorials available out there… you would be tempted to add something like this to the top of your fixture. ( this example is particularly relevant to the users fixture for use with the LoginEngine)

[source:ruby]<% SALT = "nacl" %> [/source]and then you would use this constant in your fixture somewhere… like maybe

   salt: <%= SALT %>   salted_password: <%= LoginEngine::AuthenticatedUser.salted_password     (SALT, LoginEngine::AuthenticatedUser.hashed('secret'))%> 

This is good for a single use of this fixture. But if more than one unit tests or functional tests load this fixture, you will start getting a warning “already initialize constant SALT” for all but the first use of the fixture.
Though it is just a warning, I did not find a mention of this in any of the books/tutorials.

Just a small check for an already defined constant will fix this warning.

 <% SALT = "nacl" unless self.class.const_defined?("SALT") %> 

bookmark_borderassert_tag for a hyperlink in a functional test’s response

I spent some time yesterday trying this out.
I am writing it here to save your time.

Here is the functional test’s code to check for a hyperlink with text “Back to Index” which links to the index action of the controller being tested.


link = find_tag :tag => "a", :content =>"Back to Inbox"
assert_equal @controller.url_for(:action => 'index', :only_path => true), link.attributes["href"]

It could have been done in a single assert_tag … but the statement becomes too long.

bookmark_borderRuby on Rails Presentation

I will be making a Ruby on Rails presentation at the August php meetup.

This would be my second presentation on RoR, after the one at BarCampDelhi.

The image “http://barcamp.org/f/FINAL-BAR-CAMP-LOGO2.png” cannot be displayed, because it contains errors.


And this time there will be no ppts 😉

Thanks to ValueOne for hosting the meetup.

bookmark_borderrails captcha and testing using mock objects

To prevent bots from Signing up on our application, we added a captcha to our User model. We used the validates_captcha plugin available at http://svn.2750flesk.com/validates_captcha/trunk

The plugin, selects text from a String array for the captcha challenges, so, Sur, my co-programmer, hacked the plugin a little to add random text and improved images.

After adding the plugin we realized that all our tests which validate the User model had started failing. Programmatcially a test case or a bot are not much different, they are both scripts.

Mocks to the rescue.

Here is what I wrote in a file named add_captcha_to_active_record.rb under test/mocks/test directory.


require File.expand_path(File.dirname(__FILE__) + 
"/../../../vendor/plugins/validate_captcha/lib/add_captcha_to_active_record")

module AngryMidgetPluginsInc #:nodoc:

	module Validations #:nodoc:

		# module Captcha
		module Captcha #:nodoc:

			# module InstanceMethods
			module InstanceMethods #:nodoc:

			private

				def validate_captcha(options = {}) #:nodoc:
				  
				end

			end

		end#module Captcha

	end#module Validations

end#module AngryMidgetPluginsInc

What I have done by adding this file is, I have asked the test scripts to use the validates_captcha method in /test/mocks/test/add_captcha_to_active_record.rb instead of the validates_captcha method in plugins/validate_captcha/lib/add_captcha_to_active_record.rb

Well actually Rails does all the magic, I just need to give the same file name as the one I want to mock and then define the method that I want to override.

The original validates_captcha method checks that the text entered on the signup screen is the same as that stored on the server. If these do not match it adds a validation error to the base class, the User class in our case.
In the mock validates_captcha method we just do nothing. So a validation error will never be added to the base class.

And now our tests are running and passing again.

I also noted the presence of a directory /test/mocks/development/ … well that means I can even mock classes in the development environment.
One of our application, connects to Paypal to make a payment and then returns back. During development we had commented out this code so that we are not sent to paypal everytime. Now I know how I can avoid commenting or changing the code by using mock objects.
I will be working on that soon and blog about my experiences here.

bookmark_borderemacs for windows: meadow

Meadow is a tool that I came across on my last visit to Japan.
It is a GNU Emacs imlpementation for Windows and is fairly popular in Japan.
Though i had tried the windows version of xemacs before, I like the meadow interface much more.

You can get it here.
There is an english version of the wiki here.

I sometime do a little bit of rails hacking on my windows pc too … so i installed the ruby mode.
If you would want to add ruby-mode, you can find ruby-mode.elc under your ruby installation.
Copy it to lisp/progmodes/ under meadows home.

To customize Meadow further… here is a good link ( tis in japanese, but you should understand the lisp)

bookmark_bordervalidating Rails association

Should ActiveRecord add validations based on associations defined in the models?


class User < ActiveRecord::Base 
  has_many :posts 
end 

class Post < ActiveRecord::Base 
  belongs_to :user 
end 

If i create an instance of a post with a user_id that does not exist in the Users table, I wish ActiveRecord threw up a validation error on saving this instance of post.
It does not do so by default, so here are the validations that I add to my models to implement this.


class User < ActiveRecord::Base 
  has_many :posts 
end 


class Post < ActiveRecord::Base 
  belongs_to :user 
  validates_associated :user 
  validates_presence_of :user 
end 


Now if I try and save a post without a user_id or with a user_id that is not found in the Users table, an exception is thrown.

Till now I always use to create foreign keys in my database, as a safety net. So that the db throws an error if my data is not consistent.
After adding these validations, I hope not to have foreign keys in the database anymore.

bookmark_borderPolymorphic Association in Rails

Here is an account of my first use of Rails 1.1’s polymorphism in Model associations.

I had looked at all the examples at the wiki and a couple of other blogs but still wasn’t clear.

You appreciate most, the problems that you solve yourselves 🙂

Here is the problem I solved using Polymorphic associations.

Consider the scenario where there are Users of an application; who can act as both buyers and providers. Each user can infact have multiple buyer and provider profiles.
The application also has a messaging system for users to contact each other.
As a part of the application requirement, we need to keep track of the profiles of the message sender and receiver.

A user logs in using the login name and password present in the User model. I am omitting details so please assume for this example that each logged in user, has either a buyer profile or a provider profile associated to it, when they use the messaging system.

Here are the model files

A user can have many buyer_profiles and many provider_profiles


class User < ActiveRecord::Base
  has_many :buyer_profiles
  has_many :provider_profiles
end

A buyer profile belongs to a user and can have many messages associated to it as a sender and as a receiver.


class BuyerProfile < ActiveRecord::Base
  belongs_to :user
  has_many :messages, :as => :sender
  has_many :messages, :as => :receiver
end

A provider profile also belongs to a user, and can have many messages associated to it as a sender and as a receiver.


class ProviderProfile < ActiveRecord::Base
  belongs_to :user
  has_many :messages, :as => :sender
  has_many :messages, :as => :receiver 
end

The message model holds the polymorphic magic, via the two interfaces sender and receiver. A message belongs to sender which can be polymorphic,either a buyer or a provider. And also a message belongs to a receiver, which again is polymorphic, either a provider or a buyer.


class Message < ActiveRecord::Base
  belongs_to :sender, :polymorphic => true
  belongs_to :receiver, :polymorphic => true
end

The code above requires that I have these four special fields in my messages table to handle polymorphism. Here is the migration for messages


class CreateMessagesTable < ActiveRecord::Migration
  def self.up
    create_table :messages do |t|
      t.column :sender_id, :integer
      t.column :sender_type, :string
      t.column :receiver_id, :integer
      t.column :receiver_type, :string
      t.column :subject, :string
      t.column :message, :string
    end
  end

  def self.down
    drop_table :messages
  end
end

I ran the following code on the console to check if everything is working as expected.


r = BuyerProfile.find(1)
s = ProviderProfile.find(1)
m = Message.new
m.sender = s
m.receiver = r
m.subject = "test subject"
m.message = "test message"
m.save!

And it worked 🙂

I could access profles and users from the message object like this.


m = Message.find(1)
m.receiver                 # refer to the receivers profile object
m.receiver.class          # get receiver type, where BuyerProfile or SellerProfile
m.sender                   # refers to the sender profile object
m.sender.class            # get sender type, where BuyerProfile or SellerProfile
m.receiver.user           # refer the User object of the message receiver
m.sender.user             # refer the User object of the message sender

Polymorphism saved me a lot of time and also a whole new table which I was thinking of adding to handle this functionality prior to polymorphism.

Added : And yes, now I am thinking about what I would need to write to get all the messages sent or received by a User.