Follow Along as I Stumble on the Path to Learning RoR

Rails Core

Abbreviating Numbers in Rails

I needed to abbreviate numbers in Rails so that they were shorter and easier to read.  Rails has a great built in method, number_to_human.  However, I didn’t like how number_to_human displays without any customization.

My main issue was that instead of spelling out the entire number, I just wanted to put a letter abbreviation.  In addition, I didn’t want a space between the number and its text description.

For example, “out of the box”, if you do:

number_to_human(1234)

You will get:

“1.23 Thousand”

Instead, I wanted 1.23K.

Luckily, I found this StackOverflow answer by jdoe.

To format it like this, you just need to add these values to config/locales/en.yml (or whatever you’re using as your 18n locale):

(under "en:")
  number:
    human:
      decimal_units:
        format: "%n%u"
        units:
          unit: ""
          thousand: K
          million: M
          billion: B
          trillion: T
          quadrillion: Q

Advertisements

Hiding Values from Appearing in Rails Logs

I had some fields that were sensitive, so I didn’t want the values appearing in the logs.  The solution was filtering them.  Doing that was easy.

In config/initializers/filter_parameter_logging.rb, and your fields, like so:

Rails.application.config.filter_parameters += [:password, :secret_field]

Now, when I look at the logs, I see this:

“user”=>{“password”=>”[FILTERED]”, “secret_field”=>”[FILTERED]”


NoMethodError undefined method `[]’ for “image”:Sass::Script::Value::String

When upgrading my Rails app to 4 (from 3), I was getting the error:

NoMethodError undefined method `[]’ for “image”:Sass::Script::Value::String

Eventually I found out that the asset-path / asset-url methods changed to only accept one argument.

For example,

asset-url(‘profile.png’, image)

now should be:

asset-url(‘profile.png’)

In my particular case, this code was in some of my css files.


Useful Rails Testing Gems

Here’s a list of Rails gems that have been helpful in testing for me:

RSpec Rails – for using the RSpec framework for testing

Capybara – for testing the app like a visitor would interact with the web app

Factory Girl Rails – makes it easy to create instances of models and associations

Shoulda Matchers – makes it easier to test and verify things with methods that use easy to understand language

Database Cleaner – to help keep your test environment from having a bunch of extra and redundant data

Warden – since I use Devise, this makes it easy to sign in in my Capybara tests without having to go to the login screen each time (and then to the pages I really want to test)

Guard – allows me to automatically test the code and specs that I change so I don’t need to remember to manually kick off a test each time a change is made

Launchy – useful with Capybara tests when I can’t figure out why a test is failing.  Launchy launches a browser so you can see the contents of the page.’save_and_open_page’ line to your spec when you want to do this.

 


Returning 200 Status Code for Webhook

I was getting a 500 error code because when my webhook was getting triggered, the code was looking for a view or file to render when the processing was completed.

I tried: return 200

in my controller, but that didn’t work for me.

Instead the answer was:

head :ok


Simple_Form Custom Errors

I had some error messages not appearing in simple_form because the fields they were related to did not appear in the simple_form.  Normally, simple_form will highlight the field in the form that has a problem and display the error message next to it.  However, since the field related to the error wasn’t in the form, there was no message being shown.

To solve this, I had to add some additional code to display the text of the error message.

I fixed it by adding this to my simple_form forms:

<%= render 'shared/error_messages', object: f.object %>

and then created a partial, _error_messages (shared/_error_messages):

<% if object.errors.any? %>

<% end %>


Showing Errors in the Logs

I had some errors occurring in my controller, but it wasn’t displaying in my views.  So I had to figure out how to see what was happening since I didn’t see any messages in the logs that were helpful either.

I found the solution in one of the answers here on Stack Overflow.

By adding this to my controller (it was the creation of a model – @user):

logger.warn("====error==========#{@user.error.full_messages.inspect}============")

This recorded the error in my logs (one of my model validations needed to be changed).