Engineering

Rails Active Records: Assigning a Non-boolean to a Boolean

We’ll discuss how Active Records handle data assignment to a numeric attribute. I observed this ‘odd’ behavior while working in my last epic.

We’ll work with boolean attribute here because Mysql treats boolean data as numeric. Mysql doesn’t have inherent data type called ‘boolean’. When create a column of type boolean internally stores the binary state in a ‘tinyint’ (1 byte datatype which holds integer values in the range -128 to 127). TRUE , FALSE are simple constants which evaluate to 1 & 0.

Now let’s imagine Active Record trying to work with a boolean column in mysql. What happens when we assign string data to a boolean attribute in AR. Active Record will try and coerce the data set in the attribute to a number (because boolean is numeric in mysql). Great!!! How does it convert string to int ?

I know 2 different ways this can be achieved in ruby.

1
2
3
4
pry(main)> Integer('23')
=> 23
[4] pry(main)> '23'.to_i
=> 23

Interesting to see the behavior of the above methods when try to cast a non integer to integer.

1
2
3
4
5
pry(main)> 'asdf'.to_i
=> 0
[2] pry(main)> Integer('asdf')
ArgumentError: invalid value for Integer(): "asdf"
from (pry):2:in `Integer'

The #Integer method complains whereas the use of #to_i results in 0. Unfortunately Active Record uses #to_i to set a boolean attribute and results in FALSE for any non boolean assignment. :–(

Here’s what happened :–

1
2
3
4
5
6
7
8
9
10
11
pry(main)> ds = DataSource.find(5)
  DataSource Load (0.3ms)  SELECT `data_sources`.* FROM `data_sources` WHERE `data_sources`.`id` = 5 LIMIT 1
=> #<DataSource id: 5, auto_approval_enabled: true>
[2] pry(main)> ds.auto_approval_enabled
=> true
[3] pry(main)> ds.auto_approval_enabled = 'asdf'
=> "asdf"
[4] pry(main)> ds.save!
=> true
[5] pry(main)> ds.reload.auto_approval_enabled
=> false

The world is bad. Not really ..

We only observe this behavior in Active Record 3. With Active Record 4 it throws the much needed warning for non-boolean to boolean assignment.

1
2
3
4
DEPRECATION WARNING: You attempted to assign a value which is not explicitly `true` or `false` 
("asdf") to a boolean column. Currently this value casts to `false`. This will change to match Ruby's 
semantics, and will cast to `true` in Rails 5. If you would like to maintain the current behavior, you 
should explicitly handle the values you would like cast to `false`.

Much better, right ??

Starting to Work With Databases on Linux

Starting to Work with Database on Linux

It irks and surprises me when I see engineers invoke mysql or postgres on their development box (i.e., localhost) in some funky way. These include: mysql -uroot and psql -Uroot. You should be able to work locally without pretending to be someone else. It’s just weird.

So, do yourself a favor and start right with the correct set of permissions.

MySQL

After you sudo apt-get install -y mysql-server-5.6, and install without a password issue a: mysql -uroot -e"grant ALL on *.* to $USER" mysql

PostgreSQL

After you sudo apt-get install -y postgresql, issue a: sudo su -c "psql -c\"create user $USER with SUPERUSER\"" postgres

Improve Names in Your Code

Clean Code

Clean Code by Robert C. Martin is a classic book that can be helpful to programmers of all experience levels, programming in any language. Since the advice is universal to coding, whenever I read a chapter, I find practices to use the very next time I code. Here are some thoughts from Chapter 2: Meaningful Names. I have highlighted the sub-headings used in the book in bold.

Use Intention Revealing Names – As the author says, “The name of a variable, function, or class, should answer all the big questions. It should tell you why it exists, what it does, and how it is used.” – The names you create in the process of coding can help organize your thoughts. For example, when coding a game of Tic-tac-toe, ‘determine_winner’ can be a placeholder for a method you will need in the future.

Avoid Disinformation – Only use words that have meaning to programmers if you take care to use them correctly. Examples include ‘list’ and ‘factory’.

Make Meaningful Distinctions – Avoid redundant naming, such as ‘username’ in the User class. – If you add to a concept, take care to distinguish the original name from what you have added. For example, ‘address’ and ‘address2’ have more meaning when named ‘mailing_address’ and ‘work_address’.

Use Searchable and Pronounceable Names – As the author says, “If you can’t pronounce it, you can’t discuss it without sounding like an idiot.”

Pick One Word Per Concept – Minimizing these words lends consistency to your codebase. For example, synonyms like ‘fetch’, ‘retrieve’, and ‘get’ should not be littered throughout your classes. Read through a similar file in the codebase to observe the convention, then follow it.

Now What?

These are the concepts that resonate with me. So, how can you use this information when coding tomorrow (or right now)?

  • Ask for help. If you are stumped on a name for a new class or library, talking with a co-worker can help. A quick search online can also help. Recently, I came across StackExchange’s “English Language & Usage” site when searching for a word that describes both ‘encoding’ and ‘decoding’.

  • Comment on pull requests. If you are wondering if a class, method, or test can have a better name, it probably can! You do not need to provide the ultimate solution; raising the concern can lead someone else to brainstorm something better.

  • Improve names as you code. If you add to, or change, a method significantly, ask yourself if the name continues to be suitable. If you encounter a confusing name as you code, take the time to search the codebase and replace with a better name.

Better naming leads to self-documenting code. It clearly communicates your intent and decreases the cognitive load for everyone who works in the codebase. Good luck!

Testing Your Javascript Promises

Promises

When I started working with JavaScript, I didn’t think at all about it being single threaded. As far as I was concerned, a single thread was enough to check field values, update the visibility of my components, and change some of the styles in a page. As my code got more complex, I had to face the limitations of a single thread. For example, I wanted to render new content in a section of the page, but I didn’t want to wait for the content to be loaded before updating the fields on the rest of the page.

Since I didn’t want to perfom all actions sequentially, but I still wanted to have the ability to chain actions, I started using event listeners and callbacks to handle asynchronous requests. Recently, I began exploring the world of promises. If you haven’t used them before, this is a great resource. With promises, we can do things like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function updatePage() {
  var loadPromise = new Promise(function(resolver, reject) {
    var link = loadStyleScript();
    if ('onload' in link) {
      link.onload = resolver;
      link.onerror = reject;
    } else {
      resolver();
    }
  });
  // After the stylesheet is loaded, then show the content
  loadPromise.then(showContent);

  // Hide this unrelated content without waiting for the styles
  otherUnrelatedContent.hide();
}

Promises are very powerful, but can we write tests for them? Well, we can, but it takes some effort. Now, we can leave promises in our application untested and hope for the best, but since that’s not our style, we powered through it and learned some stuff about promise testing.

Testing

We introduced the concept of JS testing with Konacha in a previous post. Now, how do we add asynchronous capabilities?

Testing that a promise works can be done in different ways. If you are returning the promise in your function, you can always do:

1
2
3
4
5
it ('should succeed!', function (done) {
  return myClass.updatePage().then(function(data) {
    done()
  });
});

Notice the done argument. This is what your test uses to know it has succeeded. If the done method is not invoked, your test will fail after a timeout. If you are not returning the promise, you can use sinon stubs to test that the promise returns successfully. Using the promise example at the beginning:

1
2
3
4
5
6
it ('should succeed!', function (done) {
  var showContentStub = sinon.stub(myClass, 'showContent', function() {
    done();
  });
  myClass.updatePage();
});

That’s neat, but what I struggled testing was the order of execution. How do I make sure that the code in the then block actually waits for the loading to be done. Again, using the promise example at the beginning, this is what I did:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
it ('should wait until the loading is done', function (done) {
  var myValue = 'beforeLoad'
  var linkStub = sinon.stub(myClass, 'loadStyleScript', function() {
    var link = $('<link href="my_app/styles.css" type="text/css" rel="stylesheet"/>');
    setTimeout(function() {
      myValue = 'afterLoad'
      link.trigger('load');
    }, 1000);
    return link[0];
  });

  var showContentStub = sinon.stub(myClass, 'showContent', function() {
    if myValue == 'afterLoad'
      done()
    else
      done('Expected value to be "afterLoad" and it was not)
  });

  myClass.updatePage();
});

The timeout adds a buffer to make sure that your loading takes some time, and your show content function is forced to wait. In our example above, passing an argument to done fails the example with the given error. Also, make sure that your timeout is not too large, otherwise your tests will fail.

It works on a browser, but…

Now, we’ve written some tests to make sure our promise succeeds, and the order of execution is right. Everything seems perfect when we run our konacha tests in our browser. However, if you run it in a console, it fails. Why?!?

Well, it seems like some headless browsers, like PhantomJS, do not support promises yet, at all. So, you can either require es6-promise, or you can copy it in a vendor file in your tests, and use that instead. Then, everything should work!

Happy Testing!

Other testing resources:

Testing Promises

Optimizing Sublime Text for Development in Ruby

Rubocop

“A Ruby static code analyzer, based on the community Ruby style guide.” – Rubocop Github page

Rubocop is a code analyzer that enforces the rules presented in the ruby style guide through static analysis. It helps you write code that adheres to the best practices in the Ruby community. You can install Rubocop by simply running $ gem install rubocop. In order for rubocop to be executed by sublime and act as a linter, you will need to install the package “SublimeLinter-rubocop.” To install the package do the following:

1
2
3
4
Open Sublime and press ctrl + shift + p (Windows, Linux) or cmd + shift + p (OS X)
Type "Package Control: Install Package" and select it
Wait for Sublime to load and then enter "rubocop"
Among the options, find "SublimeLinter-rubocop" and select it

If there are rules that you want to override then it’s as simple as adding a .rubocop.yml file to the root of your project. In that file you can specify which default rubocop rules you would like to override. Here is an example of a rule that I’m overriding to prevent rubocop from linting lines with more than 80 characters:

1
2
3
4
Metrics/LineLength:
  Description: 'Limit lines to 80 characters.'
  StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#80-character-limits'
  Enabled: false

Packages

All of thsese packages can be installed by following the steps listed above for Rubocop.

DashDoc (OS X users only)

DashDoc adds Dash integration in to Sublime. For example if you want to look up the documentation for the before_action method then you just highlight it and press ctrl + h. Doing this will open Dash and the ruby documentation for this method will be displayed.

All Autocomplete

All Autocomplete expands the autocompletion feature in sublime to search all the files that are open in the editor rather than just the file that you are working on.

GitGutter

GitGutter shows an icon in the gutter for any line that you have added, deleted, or modified.

Git Gutter

Other Packages

Here are a few other packages that add many features and shortcuts to help you be a more efficient ruby developer: Clipboard Manager, BeautifyRuby, ChangeQuotes, CoffeeScript, and RSpec.

Settings

Sublime makes it easy to customize all aspects of the editor by specifying custom settings.

Here is a list of settings that I am using (see below). I would suggest using this as a starting point to tweek things to what works best for you:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
  "auto_complete": true,
  "auto_complete_commit_on_tab": true,
  "caret_style": "solid",
  "copy_with_empty_selection": true,
  "draw_white_space": "all",
  "ensure_newline_at_eof_on_save": true,
  "font_size": 11,
  "highlight_line": true,
  "highlight_modified_tabs": true,
  "rulers":
  [
    80,
    120
  ],
  "tab_size": 2,
  "translate_tabs_to_spaces": true,
  "trim_trailing_white_space_on_save": true,
  "wide_caret": true,
  "word_separators": "./\\()\"'-:,.;<>~@#$%^&*|+=[]{}`~"
  "word_wrap": true,

}

Sublime Text 3 Only:

This setting ensures that all files in your project are indexed. This means that you can use the Goto Definition and Goto Symbol features to go directly to the spot where something is defined. This is a huge time saver.

1
"index_files": true