views:

399

answers:

6

So basically I have a controller. something like this

def show
 @user = User.find[:params[id]]
 #code to show in a view
end

User has properties such as name, address, gender etc. How can I access these properties in the model? Can I overload the model accesser for name for example and replace it with my own value or concatenate something to it. Like in the show.html.erb view for this method I might want to concatenate the user's name with 'Mr.' or 'Mrs.' depending upon the gender? How is it possible?

A: 

You can easily overload the attributes as you suggest.

i.e. if name is a field in the users database table, you can do:

def name
  "#{title} #{read_attribute[:name]}"
end

The read_attribute function will return the database column value for the field.

Caveat: I am not sure this is a good idea. If you want a method that displays model data in a modified way, I would be tempted not to overload the default methods, and call them something different - this will avoid a certain level of obfuscation.

Documentation here: http://api.rubyonrails.org/classes/ActiveRecord/Base.html (under 'Overwriting default accessors')

DanSingerman
Might want to be careful doing that as it could confuse the interface. Might be odd doing name = "Joe" and getting back "Mr. Joe".
Jamie Hale
Not to mention, this code only works if your user base contains no single ladies. ;)
Sarah Mei
@Sarah, ah, you are quite right, I will do a fix for it. @Jamie - yes I agree, hence the caveat that is in my answer.
DanSingerman
A: 

If you are accessing data stored directly in the database you can do this in you view:

<%= @user.firstname %>
<%= @user.gender %>

etc.

If you need to build custom representations of the data, then you will either need to create helpers, or extend the model (as above).

askegg
I need these in the model. I know how to get them in the view.
Daud
A: 

I tend to use helper methods added to the model for things like that:

def formatted_name
  "#{title} #{first_name} #{last_name}"
end

(Edit previous post. Looked back at my code and realized helpers are supposed to be for presentation-related (mark-up) stuff only.)

(Edit again to remove left-over parameter... Geez, not enough coffee this morning.)

(Edit again to replace $ with #... Perhaps I should just remove this one huh?)

Jamie Hale
Those dollars should be hashes.
John Topley
+4  A: 

I would hesitate to override the attributes, and instead add to the model like this:

def titled_name
    "#{title} #{name}"
end

However, you can access the fields directly like this:

def name
    "#{title} #{self[:name]}"
end
Magnar
+2  A: 

You can create virtual attributes within your model to represent these structures.

There is a railscast on this very subject but in summary you can do something like this in your model

def full_name
  [first_name, last_name].join(' ')
end

def full_name=(name)
  split = name.split(' ', 2)
  self.first_name = split.first
  self.last_name = split.last
end

If you wish to explicitly change the value of an attribute when reading or writing then you can use the read_attribute or write_attribute methods. (Although I believe that these may be deprecated).

These work by replacing the accessor method of the attribute with your own. As an example, a branch identifier field can be entered as either xxxxxx or xx-xx-xx. So you can change your branch_identifier= method to remove the hyphens when the data is stored in the database. This can be achieved like so

def branch_identifier=(value)
  write_attribute(:branch_identifier, value.gsub(/-/, '')) unless value.blank?
end
Steve Weet
A: 

in http://api.rubyonrails.org/classes/ActionController/Base.html

search for

Overwriting default accessors
penger