How can I intercept attribute calls?

Hi.

I have two types of fields in my database, e.g. “name” and “name_ru”.
First one is a user’s name in english and the second one is in russian.
I want to intercept calls like “c.name” and add “_ru” to it if current
language is russian (I have my own Locale class like n Globalize).

So I want such thing:

Locale.set(“en-US”)
c.name = “Johny English” # will be stored in the “name” column
Locale.set(“ru-RU”)
c.name = “Johny Russian” # will be stored in the “name_ru” column

What ActiveRecord class and method should I overwrite to implement such
thing?

Thanks.

P.S. I’ve googled but without any result. I’m reading Globalize’s source
code atm and I hope to get something from here.

On 7/2/06, Anton K. [email protected] wrote:

c.name = “Johny English” # will be stored in the “name” column
code atm and I hope to get something from here.

One way would be to do something like:
class Something < ActiveRecord::Base
def name_before_type_cast
if locale_is_russian
read_attribute(:name_ru)
else
read_attribute(:name)
end
end
end

I’ll leave implementing the “locale_is_russian” method up to you. Heh.

Wilson B. wrote:

On 7/2/06, Anton K. [email protected] wrote:

c.name = “Johny English” # will be stored in the “name” column
code atm and I hope to get something from here.

One way would be to do something like:
class Something < ActiveRecord::Base
def name_before_type_cast
if locale_is_russian
read_attribute(:name_ru)
else
read_attribute(:name)
end
end
end

I’ll leave implementing the “locale_is_russian” method up to you. Heh.

I can’t do that because I don’t know exact name of an attribute. It can
be “name” or “position”, or “description”.

On 7/2/06, Anton K. [email protected] wrote:

  read_attribute(:name_ru)

Is there a reason you can’t just define three methods?
def position_before_type_cast, description_before_type_cast, etc?

Are there only three, or are there numerous methods like this?

Anton K. wrote:

Wilson B. wrote:

On 7/2/06, Anton K. [email protected] wrote:

  read_attribute(:name_ru)

Is there a reason you can’t just define three methods?
def position_before_type_cast, description_before_type_cast, etc?

Are there only three, or are there numerous methods like this?

I don’t know what methods will I need. It depends on db scheme (as
usual) and on translates method (as in Globalize: translates :name,
:bla, :bla, …).

Actually, I already have a solution:

class ActiveRecord::Base
def self.multilingual_field(fieldname)
module_eval <<-end_eval
def #{fieldname}
send(“#{fieldname}_#{Locale.language.short_name}”)
end

  def #{fieldname}=(value)
    send("#{fieldname}_\#{Locale.language.short_name}=",value)
  end
end_eval

end
end

Wilson B. wrote:

On 7/2/06, Anton K. [email protected] wrote:

  read_attribute(:name_ru)

Is there a reason you can’t just define three methods?
def position_before_type_cast, description_before_type_cast, etc?

Are there only three, or are there numerous methods like this?

I don’t know what methods will I need. It depends on db scheme (as
usual) and on translates method (as in Globalize: translates :name,
:bla, :bla, …).

Wilson B. wrote:

Cool. Be warned that the built-in Rails form helpers don’t call the
attribute directly, though.
They call attribute_before_type_cast.

text_field :something, :name will still show the ‘raw’ column value,
unless you implement the before_type_cast methods.

Wow, I didn’t know about this. Thanks a lot.

On 7/3/06, Anton K. [email protected] wrote:

I don’t know what methods will I need. It depends on db scheme (as
end

  def #{fieldname}=(value)
    send("#{fieldname}_\#{Locale.language.short_name}=",value)
  end
end_eval

end
end

Cool. Be warned that the built-in Rails form helpers don’t call the
attribute directly, though.
They call attribute_before_type_cast.

text_field :something, :name will still show the ‘raw’ column value,
unless you implement the before_type_cast methods.