Thursday, July 23, 2009

Eartheternal Team

I have been working on a MMO website for the past few months. Here is the pic of the team covered by Massively.

Massively: Meet the Team



Shared via AddThis

Thursday, June 25, 2009

"Type" column in legacy databases

Rails will look for the STI classes which you don't need in this case. The workaround is:-

class EventLog < ActiveRecord::Base

set_table_name 'EventLog'


def self.inheritance_column
nil
end

def category
read_attribute :type
end

end

Suppress the STI by overriding inheritance column.
Define a method that reads type otherwise type will always return you the class

Friday, August 22, 2008

Extending Globalize

Came across an interesting situation where i had a simple edit form where the translator is supposed to enter the description of the selected product and the data will be stored as the current language translation for which the Locale is set. The application uses globalize for localization. The problem was that i had to access the native description of the product(in english) as well and display it on the same page to make it easy for the translator. I came up with a very generic solution a module that can be included in any model and will give you a method get_native_attribute_name that will give you the value of the specified attribute in the base language of your app(in this case english)
Here is the code

module NativeAttributes

def self.included(base)
base.class_eval do
alias_method :method_missing_without_native_attrs, :method_missing
include NativeAttributes::InstanceMethods
end
end

module InstanceMethods
def get_native_attribute(attrib)
table = self.class.table_name
self.class.find_by_sql("select #{attrib} from #{table} where id = #{self.id}").first.send(attrib)
end

def method_missing(meth, *args,&block)
if meth.to_s.include?('get_native_')
current_locale = "#{Locale.active.language.code}-#{Locale.active.country.code}"
Locale.set('en-US')
self.reload
native_attribute = self.get_native_attribute(meth.to_s.gsub('get_native_',''))
Locale.set current_locale
self.reload
return native_attribute
else
method_missing_without_native_attrs(meth,*args,&block)
end
end
end
end

Friday, May 30, 2008

active_scaffold Woes

I recently used this plugin in my current project to build the admin interface. It works great but I faced an interesting problem that i would like to share with an example.

class Order < ActiveRecord::Base
has_many :products
end

If you see the page generated using scaffolding for the Order model you will see some links to the products in one of the columns for each Order (provided you have included products as one of the attributes in the scaffolding configuration). Lets say you are not much interested in those links, you just want the count of products. You can use active record field overrides to achieve this by putting a helper method in your OrderHelper

module OrderHelper
def products_column(record)
record.products.size
end
end

For a small number of records it works well but as the number grows it becomes very slow because of the join query it makes behind the scenes and for a few thousand records it may actually hang your database server for a while.

So to avoid this, there is a simple way out, just use the virtual attributes. Create a virtual attribute for the Order model that returns the product count and include that as an attribute in the active scaffolding.

Tuesday, May 6, 2008

RMagick Tricks

Kudos to this great library but sometimes you are stuck with certain tasks where you have to look for some workarounds.
One of the common tasks is to wrap the text on in image.
You can accomplish it very well like this

image = Image.read("caption: text goes here")

You can specify other arguments by setting Image::Info attributes in the optional block like this

image = Image.read("caption: text goes here") do
self.size = "200x"
self.pointsize = 20
self.font = "Tahoma"
end
But the Image::Info class is a bit restricted e.g you can't set the font weight, style and a lot more things that you can do you using the Draw class.
So the best workaround is to insert "\n"s into the text.
To do this create your draw class object and call its method get_type_metrics and pass it the text and the image where you want to draw the text or any temporary image.

# create draw object
draw_title = Magick::Draw.new
# set the attributes
draw_title.stroke('transparent')
draw_title.font_family('Georgia')
draw_title.pointsize(17)
draw_title.font_stretch(Magick::UltraCondensedStretch)
draw_title.font_style(Magick::NormalStyle)
draw_title.font_weight(500)
draw_title.fill = '#000000'
tmp_img = Magick::Image.new(600,600)
tmp = draw_title.get_type_metrics(tmp_img, "You text goes here").

You can easily find where to put the "\n" by looking at tmp.width.

Wednesday, April 16, 2008

JQuery VS Prototype

I have been using prototype in all my previous Rails projects but switched to JQuery recently and i found it much better than prototype. The difference is not only in the code size but also in the approach they have for the same problem. Lets explore this with an example. Lets consider a simple fade effect that you wanna produce on a DOM element.

Prototype way - Effect.Fade('someId', {duration: 0.5});

Prototype uses classes that encapsulate some functionality, we just need to pass the ids and other optional parameters and the class does what it is supposed to do.

JQuery way - $("someId").fadeOut(1000);

JQuery instead sees all the html nodes as objects to pass messages to. And when you pass a message to an object it returns you a JQuery object to which you can further pass some messages..... sounds more like the oops way....Its pretty easy to operate on list of elements on your page using JQuery.
And also once you are comfortable with the JQuery syntax you can easily use Hpricot test extension to test your Rails views.