Mene
Mene

Reputation: 354

Rails 4 - Titleize on read, downcase on save, in model

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

Upvotes: 0

Views: 989

Answers (3)

Richard Peck
Richard Peck

Reputation: 76774

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" %>

Upvotes: 0

Joe Kennedy
Joe Kennedy

Reputation: 9443

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.

Upvotes: 0

SteveTurczyn
SteveTurczyn

Reputation: 36860

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

Upvotes: 2

Related Questions