# How can I intercept attribute calls?

**URL:** <https://www.ruby-forum.com/t/how-can-i-intercept-attribute-calls/96865>\
**Category:** Rails\
**Created:** [July 2, 2006, 10:11pm UTC](https://www.ruby-forum.com/t/how-can-i-intercept-attribute-calls/96865 "2006-07-02T22:11:58Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![antonk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a5b964/32.png) [@antonk](https://www.ruby-forum.com/u/antonk)\
**Post date:** [July 2, 2006, 10:11pm UTC](https://www.ruby-forum.com/t/how-can-i-intercept-attribute-calls/96865/1 "2006-07-02T22:11:58Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![antonk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a5b964/32.png) [@antonk](https://www.ruby-forum.com/u/antonk)\
**Post date:** [July 2, 2006, 10:42pm UTC](https://www.ruby-forum.com/t/how-can-i-intercept-attribute-calls/96865/2 "2006-07-02T22:42:04Z")

</div>

On 7/2/06, Anton K. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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.

---

<div class="post-metadata">

**Author:** ![antonk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a5b964/32.png) [@antonk](https://www.ruby-forum.com/u/antonk)\
**Post date:** [July 3, 2006, 1:58am UTC](https://www.ruby-forum.com/t/how-can-i-intercept-attribute-calls/96865/3 "2006-07-03T01:58:40Z")

</div>

Wilson B. wrote:

> On 7/2/06, Anton K. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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”.

---

<div class="post-metadata">

**Author:** ![antonk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a5b964/32.png) [@antonk](https://www.ruby-forum.com/u/antonk)\
**Post date:** [July 3, 2006, 2:05am UTC](https://www.ruby-forum.com/t/how-can-i-intercept-attribute-calls/96865/4 "2006-07-03T02:05:39Z")

</div>

On 7/2/06, Anton K. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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?

---

<div class="post-metadata">

**Author:** ![antonk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a5b964/32.png) [@antonk](https://www.ruby-forum.com/u/antonk)\
**Post date:** [July 3, 2006, 2:27pm UTC](https://www.ruby-forum.com/t/how-can-i-intercept-attribute-calls/96865/5 "2006-07-03T14:27:02Z")

</div>

Anton K. wrote:

> Wilson B. wrote:
> 
> > On 7/2/06, Anton K. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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

---

<div class="post-metadata">

**Author:** ![antonk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a5b964/32.png) [@antonk](https://www.ruby-forum.com/u/antonk)\
**Post date:** [July 3, 2006, 2:23pm UTC](https://www.ruby-forum.com/t/how-can-i-intercept-attribute-calls/96865/6 "2006-07-03T14:23:31Z")

</div>

Wilson B. wrote:

> On 7/2/06, Anton K. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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, …).

---

<div class="post-metadata">

**Author:** ![antonk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a5b964/32.png) [@antonk](https://www.ruby-forum.com/u/antonk)\
**Post date:** [July 3, 2006, 7:35pm UTC](https://www.ruby-forum.com/t/how-can-i-intercept-attribute-calls/96865/7 "2006-07-03T19:35:26Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![antonk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a5b964/32.png) [@antonk](https://www.ruby-forum.com/u/antonk)\
**Post date:** [July 3, 2006, 6:38pm UTC](https://www.ruby-forum.com/t/how-can-i-intercept-attribute-calls/96865/8 "2006-07-03T18:38:41Z")

</div>

On 7/3/06, Anton K. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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.
