Forum: Ruby on Rails model filter?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Dave C. (Guest)
on 2006-05-09 06:42
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!
Randy (Guest)
on 2006-05-09 09:32
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.
Dave C. (Guest)
on 2006-05-09 17:35
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!
Daniel -. (Guest)
on 2006-05-10 03:39
(Received via mailing list)
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
Wilson B. (Guest)
on 2006-05-10 04:13
(Received via mailing list)
That needs to be:
def phone_number
  number = read_attribute(:phone_number)
  number.do_formatting_stuff
end
Ben and Kaz A. (Guest)
on 2006-05-10 05:05
(Received via mailing list)
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
Daniel -. (Guest)
on 2006-05-10 05:24
(Received via mailing list)
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
Wilson B. (Guest)
on 2006-05-10 06:15
(Received via mailing list)
>> > 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.
Dave C. (Guest)
on 2006-05-10 06:25
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...?...
Wilson B. (Guest)
on 2006-05-10 07:56
(Received via mailing list)
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.
Ben and Kaz A. (Guest)
on 2006-05-10 09:42
(Received via mailing list)
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
Dave C. (Guest)
on 2006-05-10 17:52
> 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
This topic is locked and can not be replied to.