user3673826
user3673826

Reputation: 243

Ruby on Rails: before_save fields to lowercase

I'm trying to change the fields from the form to lower case before they get saved in the database. This is my code but the output from the database is still in upper case why isnt the code working?

class Transaction < ActiveRecord::Base
   validates :name, presence: true
   validates :amount, presence: true, numericality: true
   before_save :downcase_fields

   def downcase_fields
      self.name.downcase
   end
end

Upvotes: 24

Views: 20392

Answers (6)

Cruz Nunez
Cruz Nunez

Reputation: 3139

Another solution is to remove the before_save and monkeypatch the initialize method

def initialize(args = {})
  args[:name].downcase! if args[:name]
  super
end

Then you can say something like

irb(main)> t = Transaction.new name: 'BIGTRANSACTION'

irb(main)> t.name

=> "bigtransaction"

This solution edits the behavior at instantiation instead of at creation, which can be useful if you need to check the edited value before saving anything to the database. For example, if you also need to run validations on the attribute.

Upvotes: -7

Gamaliel
Gamaliel

Reputation: 465

Other simple example with less code:

class Transaction < ActiveRecord::Base
   validates :name, presence: true
   validates :amount, presence: true, numericality: true

   before_save { self.name.downcase!}

end

Hope this helps!

Upvotes: 4

justapilgrim
justapilgrim

Reputation: 6872

You're not setting name to downcase by running self.name.downcase, because #downcase does not modify the string, it returns it. You should use the bang downcase method

self.name.downcase!

However, there's another way I like to do it in the model:

before_save { name.downcase! }

Upvotes: 7

hjing
hjing

Reputation: 4982

String#downcase does not mutate the string, it simply returns a modified copy of that string. As others said, you could use the downcase! method.

def downcase_fields
  name.downcase!
end

However, if you wanted to stick with the downcase method, then you could do the following:

def downcase_fields
  self.name = name.downcase
end

This reassigns the name instance variable to the result of calling downcase on the original value of name.

Upvotes: 4

Matus Cimerman
Matus Cimerman

Reputation: 447

You need to use exclamation mark after calling method downcase, if you also want to save result of operation to the variable. So for you will be usable:

self.name.downcase!

Don't forget that .downcase! replacement works only in ASCII region.

Upvotes: 2

Gergo Erdosi
Gergo Erdosi

Reputation: 42048

downcase returns a copy of the string, doesn't modify the string itself. Use downcase! instead:

def downcase_fields
  self.name.downcase!
end

See documentation for more details.

Upvotes: 39

Related Questions