0

I'm sure it's a pretty dumb question but I can not figure it out.

In my user model I have a

`before_save :downcase_username` #because I use custom subdomain for each user with request

def downcase_username
  self.username = username.downcase
end

However, I would like to titleize the username each time it is visible (read?) in view without specifying each time user.username.titleize. I do not know which before_ to call inside model, in controller I would have use a before_action. Moreover, Is there a way to automate this for all the values of a model ? (always titleize just in view)

Any hint appreciated.

Thank you very much

Mene
  • 344
  • 2
  • 14
  • I'm glad my answer was helpful! Decorator objects are specifically there to solve these sorts of problems, particularly since presentation shouldn't really be the User object's concern. You should look at the Draper gem https://github.com/drapergem/draper and you'll find it gives you a lot of flexibility and it's easy to use... instead of doing `@user.find(params[:id])` you simply do `@user.find(params[:id]).decorate` and all your custom getters are in place. – SteveTurczyn Jun 21 '14 at 11:41

3 Answers3

2

You could make a custom getter...

class User < ActiveRecord::Base
  def username
    self[:username].titleize
  end
end

If you want it only on reads for views but not on reads for edits then you might be better off using a decorator.

https://github.com/drapergem/draper

SteveTurczyn
  • 36,057
  • 6
  • 41
  • 53
  • Thank you very much. In fact, I've seen this way of act, but I weren't sure about overiding the default attribute, and the consequences on getter and setter. Thats brings me to a user.title_username custom method, still wordy. – Mene Jun 21 '14 at 10:28
0

I believe the after_initialize method should do the trick for you. All after_initialize methods are called every time an object is grabbed from the database.

class User < ActiveRecord::Base
  after_initialize :titleize_username # in your case you'd wrap this in backticks

  def titleize_username
    self.username = username.titleize
  end
end

For more information about callbacks, check out the Rails Guide on Callbacks.

Joe Kennedy
  • 9,365
  • 7
  • 41
  • 55
0

Getter / Setter Methods

@SteveTurczyn is right - you need a custom getter

Basically, whenever you call model data, Rails basically uses a series of setter & getter methods to create the attributes you see. This would basically look something like this:

#app/models/user.rb
Class User < ActiveRecord::Base
   def attribute
       "value"
   end
end

The getter methods are basically instance methods which allow you to call Object.getter in your view / controller. This means if you only wanted to titleize in the view, you could use a getter in your model to set it when you read the object (setters set the attribute)


CSS

Another option you have is to use CSS (text-transform: capitalize)

This is a far more efficient way to handle styling options on your front-end is to use the CSS. Instead of using resource-intensive ruby methods for a simple styling issue, you will be better setting a class in your view, and then capitalizing that:

#app/assets/stylesheets/application.css.scss
.title_text {  text-transform: capitalize; }

#app/views/your_controller/index.html.erb
<%= content_tag :div, @user.example_content, class: "title_text" %>
Community
  • 1
  • 1
Richard Peck
  • 76,116
  • 9
  • 93
  • 147
  • 1
    Thank you a lot for all these detailled explanations. I didn't even think about css styling, sounds like an evidence now... – Mene Jun 21 '14 at 10:32
  • 1
    I'll need to style the whole set of attributes from a model. Since I stored them with dash and downcase, I'll have to use titleize for them I guess – Mene Jun 21 '14 at 10:59