Model filter?


#1

Hi All,

Is there a way to filter / modify the output of a model class before
it’s returned to controller/view that’s calling it?

Example: I have a field phone_number which I always want to preformat
using the number_to_phone() helper…

Any help is appriciated.

Thanks!


#2

I believe the best way would be to write a new method in your model.rb
file.
Call it something like phone_number_formatted or something and just use
that new method (model.phone_number_formatted) instead of the
rails-generated model.phone_number method.

I could be wrong as I’m still learning too.


#3

Randy wrote:

I believe the best way would be to write a new method in your model.rb
file.
Call it something like phone_number_formatted or something and just use
that new method (model.phone_number_formatted) instead of the
rails-generated model.phone_number method.

I could be wrong as I’m still learning too.

Yeah, I was kinda looking for some way to call that method always from
the model after the data was loaded, much the same way you would with
before_validation, before_save, after_save etc.

Like an after_load or something.

There’s an after_filter, but I think that doesn’t apply to active
record…

Haven’t found anything in the API docs that would do what I’m thinking,
but still looking.

Thanks!


#4

If you just want to format it as you go, then overwrite the getting
attribute method that Active Record provides.

Ie if you column is phone_number

def phone_number
a = self.phone_number
some formatting stuff on a

end

Whenever you call the @obj.phone_number you will get the format that
your
after.

This should probably go into a helper tho or save it in the format that
you
want with a call to before_save.

Cheers


#5

That needs to be:
def phone_number
number = read_attribute(:phone_number)
number.do_formatting_stuff
end


#6

On 5/10/06, Wilson B. removed_email_address@domain.invalid wrote:

That needs to be:
def phone_number
number = read_attribute(:phone_number)
number.do_formatting_stuff
end

Nice, so read_attribute avoids the recursive road to hell I was
experiencing
on the weekend! Thanks Wilson.

cheers,
Ben


#7

Wilson,

Thanx for the fixup.

I can’t find any documentation for the read_attribute method on the doc
site.

Any hints as to why you use that instead of just self.phone_number

Cheers


#8

Awesome. That worked great!

One thing that didn’t work though…

I have this in my addressbook model:

def phone
format_phone(read_attribute(:phone), {:delimiter => “-”})
end

format_phone is just a copy of number_to_phone() helper since it’s not
inherited by ActiveRecord.

If I do this: <%=@addressbook.phone%>
the output is: 513-545-3333
which is what is desired.

If I do this:
<%=text_field ‘addressbook’, ‘phone’, :size => 10, :class => ‘input’%>
I get: 5135453333 as the value of the text field (no formatting)

Weird…?..


#9

end

Nice, so read_attribute avoids the recursive road to hell I was experiencing
on the weekend! Thanks Wilson.

On 5/9/06, Liquid removed_email_address@domain.invalid wrote:

read_attribute and write_attribute are the behind-the-scenes accessors
for the attributes that ActiveRecord plucks from the database.
Are they really not in the API docs? That seems odd. Oh well.

The main reason to use them is when you’re redefining/overriding a
method with the same name.
In the example above, self.phone_number will call the phone number
method you just defined… an endless loop.

read_attribute lets you essentially delegate the work to ActiveRecord.


#10

On 5/10/06, Wilson B. removed_email_address@domain.invalid wrote:

On 5/9/06, Liquid removed_email_address@domain.invalid wrote:

Wilson,

Thanx for the fixup.
read_attribute and write_attribute are the behind-the-scenes accessors
for the attributes that ActiveRecord plucks from the database.
Are they really not in the API docs? That seems odd. Oh well.

Just, checked. It’s there in the ActiveRecord::Base under the heading
“Overwriting default accessors”. Thanks for the tip.

cheers,
Ben


#11

Try adding:
alias_method :phone_before_type_cast, :phone
…below the definition of your phone method.

If that’s what it takes to make it work, that’s fairly irritating.

That worked great also, thanks.

Only problem is, I’m using before_type_cast to unformat the phone number
before validating…

before_validation :unformat_phone

def unformat_phone
phone_before_type_cast.gsub!(/\D/, “”)
end

Thanks allot for your help. I’ve learned a bunch trying to get this to
work. Guess I’ll just write out the phone number text field the old
fashioned way… or write my own helper.

Thanks again,

Dave


#12

On 5/9/06, David C. removed_email_address@domain.invalid wrote:

format_phone is just a copy of number_to_phone() helper since it’s not
Weird…?..

I just walked through what text_field does, and it ends up calling
attribute_name_before_type_cast.

Try adding:
alias_method :phone_before_type_cast, :phone
…below the definition of your phone method.

If that’s what it takes to make it work, that’s fairly irritating.