On 4/18/07, Kris Helenek <khelenek / hotmail.com> wrote:
> I'm very new to ruby, coming from a long j2ee background. I hope these
> questions make sense and aren't covered elsewhere (i looked, really.)
>
> I'm creating a project in rails and i have several model objects that I
> want to override the to_s method on.  It looks like using a "mixin" or
> module is the way to go since i don't want to write a new to_s for every
> model class that i have to update every time i make a change to the db.
>
> In java my model classes would use reflection to discover all the
> instance variables and concatenate them together (the apache commons
> ToStringBuilder.)
>
> I went to accomplish that for my ruby model class but honestly could not
> figure out how.  I was first stumped trying to override the to_s in the
> first place by putting
>
> Class Member
>   def to_s
>     "Member[" + @first_name + ", " + @last_name + "]"
>   end
>
> And that fails out on me (@first_name is nil!)
>
> Then i switched it to
>   def to_s
>     "Member[" + first_name + ", " + last_name + "]"
>   end
>
> And that worked.  I don't get it, i thought instance variables always
> started with the @?
>
> So i guess my questions are, why no @ before my instance variables, and
> how would i write a method that gets all instance variables (and then
> concatenates them, although i can figure that out. hopefully ;)
>

Because @first_name is apparently not a instance variable in rails models:

Have a look:

>> small_user = User.find(:first)
>> small_user.methods.grep(/instance/)
=> ["copy_instance_variables_from", "instance_variables",
"instance_variable_get", "instance_variable_set", "instance_values",
"instance_exec", "instance_of?", "instance_eval"]

>> small_user.instance_variables
["@attributes"]

So, your second attempt worked, because every column is an attribute
and rails creates accessor methods for them.

If you want to override #to_s method for all your models, then an easy
solution would be

module Foobar
  def to_s
     #put your foobar here
  end
end

And mix this module, in all your models where you want to override
behaviour of #to_s. I haven't tested this approach although.




-- 
gnufied