Monday, December 28, 2015

Bash yourself in the background!

There are many occasions for wanting to run bash scripts in the background. The two that jump out at me are startup scripts and scripts to be run while SSH-ed into a remote server. This post deals mainly with the latter, though it should work for both.

First, create a bash script you want to run. I wanted to monitor the memory of a running EC2 server instance to ensure we didn’t have memory leaking from our app, so here’s my bash script:

# log/memory_profiler.sh
while true
 do
    date 2>&1 | tee -a /srv/application/my_application/log/memory
    free -m 2>&1 | tee -a /srv/application/my_application/log/memory
     sleep 1
 done

This writes the current datetime and the current memory profile to a log file in my app’s directory.

Then, I wanted to run this script from a detached shell session so that when I closed my SSH connection, it would continue running, and also so that I could continue working within the open shell session. To do this, I use a tool called “screen.” Here’s my command:

screen -d -m -S "Memory Profiler" bash log/memory_profiler.sh

Here’s what’s happening: We run the bash script in a detached (-d) shell session, named (-S) “Memory Profiler”. The -m flag ensures a new shell session is created, regardless of where the screen command is called.

Simple enough, right? Then, to view what’s going on with this detached screen session, you just have to reattach the shell session. If you only have one screen running, enter

screen -r

If multiple, you’ll have to specify the named session.

screen -r "Memory Profiler"

Exit as normal using ctrl+c or typing exit.

If you want to get really fancy, you can run this on a schedule - something I've written about previously.

(Lots of good info in the screen docs.)

Monday, December 21, 2015

Funky Ruby Class Method Syntax

I’ve run across this syntax a few different times but never grasped how it worked, and I guess never cared enough to look it up. Turns out it’s dead simple.

This:

class Person  
  def self.species
    "Homo Sapien"
  end
end

is equivalent to this:

class Person  
  class << self
    def species
      "Homo Sapien"
    end
  end
end

Thanks to Yehuda Katz for finally clearing that up for me.

Monday, December 14, 2015

Literally the coolest way to build an array

One of Ruby’s literal syntax shorthands, %i essentially loops over each word, converts to a symbol and adds it to an array. For example:

%i(dog cat mouse)
# => [:dog, :cat, :mouse]

Caveat: This syntax was added in Ruby 2.0, so don’t go trying it in any previous version.

Monday, December 7, 2015

Familiarize quickly in new code with this trick

Here’s a quick and nifty little trick that comes in extremely handy in a lot of situations, but particularly when dealing with an unfamiliar codebase, such as at a new job or working with a previously unused external gem.

In the rails console, enter:

ls Model 

and it will show all the class and instance methods, as well as associations and a bunch of other cool stuff for that model.

I’ve begun using this in place of these two:

Model.methods
Model.new.methods

Not only because it’s simpler with less typing but it else ends up being much easier to read.

Monday, November 30, 2015

Bash yourself on a schedule!

To run terminal tasks on a schedule, you have to use something called the “crontab.” It is a file that you edit to include the bash code to run and the times and days to run it.

There are some interesting rules/best practices around editing the crontab.

To start, you have to create a crontab by entering crontab -e. Open and edit it in your favorite editor and save.

If you already have a crontab file that you want to edit, you actually shouldn’t. Rather, get a “copy” of your crontab file by doing crontab -l > new_crontab_copy. Then open the new_crontab_copy in your editor, edit and save.

For either of the above options, “install” your crontab file by giving it to crontab:
crontab my-crontab

(This post won’t be giving any advice on actually writing cron jobs - for that you can check out this Crontab quick reference.)

Monday, November 23, 2015

count vs size on ActiveRecord select queries

I stumbled on this bit of weirdness when using the SQL query User.select(:id, :name, :email).count. It threw a PG::UndefinedFunction error. Using User.select(:id, :name, :email).size worked instead.

Out of curiosity, I did some digging. According the the ActiveRecord docs,
not all valid select expressions are valid count expressions. The
specifics differ between databases. In invalid cases, an error from
the database is thrown.
I also stumbled on an issue on rails Github issues page about this, and a very helpful comment from rafaelfranca explained that I can also use count(:all).

Monday, November 16, 2015

Ctrl-Alt-Del for Linux

Back in my Ubuntu days, I had some issues with my computer locking up, and I didn’t know Linux well enough to break free. Once I found out about this trick, I was able to unlock 90% of the time.

The easiest way for me to remember was “BUSIER” spelled backwards.
  1. Hold down the Alt and SysRq (Print Screen) keys
  2. Type, the following, pausing one second between each - “R”, “E”, “I”, “S”, “U”, and “B”
Follow the link if you want to know exactly what all these key presses are doing.

Magic SysRq Key | Wikipedia

Monday, November 9, 2015

Intro to SSH for relative newbies

I have an app running on an Amazon EC2 instance, and it requires an SSH key to access it. Previously, I had to access it by navigating to the folder containing my private key pem file, then running ssh -p 2222 -i private_key.pem -A ubuntu@www.example.com.

Let’s break this down a bit.
  • -p 2222 - the port that my server runs on
  • -i private_key.pem - use an Identity File (SSH key) and specify the name
  • -A - use ForwardAgent to allow my public keys to pass through to the AWS server (important if I want to be able to access Github or some other service while SSH-ed into the server)
  • ubuntu@www.example.com - username (ubuntu) and server HostName (www.example.com)
This is all fine and dandy, but it’s a pain to remember. So, my next step to simplify this was setting up a terminal alias in ~/.bash_aliases

alias my-server-ssh="cd ~ && ssh -p 2222 -i private_key.pem -A ubuntu@www.example.com"

This lets me simply run my-server-ssh from whatever directory I’m in on the terminal and automatically login to my server. However, once I have a couple more servers to juggle, it starts to get troublesome keeping track of these things. It’s also problematic if I want to use a tool like Capistrano for deployment.

Here’s where setting up the ~/.ssh/config file comes in handy. I opened this file in my text editor, and entered this info:

Host my-server
    HostName www.example.com
    Port 2222
    User ubuntu
    IdentityFile "~/.ssh/private_key.pem"
    ForwardAgent yes

Once I save, I can now use my computer’s built in SSH manager to access my server by running the command ssh my-server. Then, in a tool like Capistrano, I can plug this line into my config file:

server 'my-server', roles: %w{app web}

It will read my ~/.ssh/config file, find the configuration for host my-server and SSH in.



Big ups to Nerderati for the helpful explanation on SSH config.

Monday, November 2, 2015

Object overload! Careful of instantiating objects in Ruby

Wowzers, I just tackled a major memory issue in an app I’ve been developing, and it was nearly all due to rampant over-instantiation of ActiveRecord objects.

Here’s the TL;DR: Use SQL queries whenever possible to grab info from the database, rather than using Ruby code.

Now for the longer version. First, I knew I had a memory issue because my server was crashing and it was showing up the logs saying that memory could not be allocated. But I had to find out what the issue was first.

Oink to the rescue. It’s a handy little Ruby gem that will log how much memory and how many ActiveRecord objects are instantiated for each request.

I installed Oink, ran through a few requests that seemed kinda slow, and lo and behold, I found the problem: One of my requests was generating 1500 objects!

Here’s what was happening. I was looping through an array of IDs, and for each one I was calling

account.users.order(:id).select{ |user| user.id == id }.first

Don’t laugh. I have a baby at home, I was sleep deprived, I don’t know why I did it this way. But yes, this is instantiating all User objects in an account, and it’s doing it every single time it iterates through the loop. Hence, 1500 objects instantiated per request.

This was easily solved by a simple find_by_id with the id from the array.

That took me down to only one instance of each User object, which is still not fantastic. So, I ended up using one of my favorite ARel methods, pluck, to get just the attributes of the users that I need without actually creating the User objects.

That’s the ticket! From 1500 User objects to 0, this should significantly help with speed and memory usage. I ended up combing through the rest of the app and finding a few other spots where object instantiation was a bit out of control, though not nearly as bad as that one.

It became a kind of game - and in the end, I’d say I won.

Thanks to Engine Yard for the great tips. Lots more in their linked post.

Monday, October 26, 2015

Debugging Capybara Poltergeist tests in Rails

I made the switch from selenium webdriver to poltergeist on my capybara tests when the suite started taking 20 minutes to run. (For my process of getting the test suite under control, check out my previous post.) While poltergeist has definitely been a boon, it can sometimes be hard to debug because I can’t physically see the page. That’s where this tip comes in handy, stolen from the Quickleft blog:

Find the Port Address and Pause the Test 
Sometimes I just want to see what's going on in the browser. Although save_and_open_page gives you some idea of what's going on, you can't really click around, because the page it gives you is static and lacking assets. To dig into what's going on, I like to use a trick I learned from my mentor, Mike Pack. 
Just above the broken line in your test, add these two lines of code. Note that you have to have pry installed in your current gemset or specified in the Gemfile for this to work. 
puts current_url
require 'pry'; binding.pry 
Run the specs, and when they pause, copy the url and port number from the test output. 
Open your browser and paste the address into the window. Voila! You're now browsing your site in test mode!

Thanks again to the Quickleft folks for this cool tip - it’s one of five tricks for less painful testing.

Monday, October 19, 2015

Device Emulators all up in your browser

File this one under the "n00b" tag.

For checking responsiveness on mobile, Chrome (and probably Firefox) has some sweet device emulators.

Go to Developer Tools, then click the little phone icon in the far left of the Developer Tools nav
and it will let you select whatever device to see how the current page looks.

Wow. Much responsive. Very browser.


Monday, October 12, 2015

URL Encoding and Silly Safari

I have a web app that also acts as an API for an iOS, and I ran into a tricky situation. One of my models on the web app takes a URL as input, and it validates it using the validates_url gem. However, some URLs when visited from within the iOS app would give a Webkit error and show as invalid.

After some head scratching, it turned out that those URLs had encoding issues that were handled fine by all modern browsers except Safari, the default browser on iOS. For example, something with curly brackets like "http://www.example.com?ID={12345}" would work in most browser but not in Safari/iOS.

To get around this, in addition to using validates_url, I had to escape each URL during validation using URI.escape(url). The above URL would then become "http://www.example.com?ID={12345}". (Notice that the left curly bracket changed to %7B, the right turned to %7D - check out this HTML URL Encoding Reference for details)

But wait, there’s more!

It turns out that on subsequent saves, the URL would be escaped again, and it wouldn’t recognize the %7B and %7D as encoding, it would just see the % sign as an invalid character needing escape. So, on the second save, the same URL would be transformed again into "http://www.example.com?ID=%7B12345%7D". Notice the “25” inserted in there twice?

The fix ended up being something that reads very strange and seems unnecessary, but that works perfectly:

URI.escape(URI.unescape(url))

So, if a URL is already escaped, it unescapes it first, then re-escapes it. If the URL is not escaped, then unescaping it does nothing, then it gets escaped as it should.

If there’s a better way to do this, I haven’t found it, and am open to suggestions.

Tuesday, October 6, 2015

Refactoring using guard clauses

This post is almost purely about code style, but it’s an approach to coding and refactoring that I just found and really enjoy for its simplicity and readability.

The secret sauce to this approach is called a guard clause.

Say I have a method that I’m writing where I want to return one thing is a condition is true, another thing if it’s false. The way I used to write the code is exactly how I wrote that sentence:

def do_something_conditionally(fact)
    if fact == true
        fact
    else
        false
    end
end

Pretty standard, right? Now check out the same example with a guard clause:

def do_something_conditionally(fact)
    return false unless fact == true
    fact
end

We saved a couple lines of code, which is nice (although I could’ve saved more turning the conditional into ternary (fact == true ? fact : false)). However, the big gain from doing it this way is that it’s easier to read. Disagree?

It may help to have a more complex example, perhaps using nested conditionals:

def account_type
    if has_problems?
        type = "problems"
        if is_past_due?
            type = "past due"
            if is_weeks_past_due?
                type = "delinquent"
            end
        end
    else
        type = "normal"
    end
    type
end

…and now with guard clauses:

def account_type
    return "delinquent" if is_weeks_past_due?
    return "past due" if is_past_due?
    return "problems" if has_problems?
    "normal"
end

We’ve saved more lines of code, this time something we could not have easily change to ternary, and it’s harder to argue that this isn’t more readable now.

If all of that isn’t convincing enough, check out the quasi-official Ruby Style Guide, because it also recommends using guard clauses when possible.

Monday, September 28, 2015

Asynchronous processing pitfalls and ActiveRecord locking

My app is humming along, but there are a few sections that have to do a lot of heavy lifting, whether that be image processing, updating several different related objects, or looping through all of a has_many association to manipulate every record.

These types of things are perfect places to push some logic to a background process. In other words, make it asynchronous. So, if a user clicks a button to update several objects, unless the user needs to see those updates completed immediately, then a tool like Sidekiq can help run some expensive logic as a background process and allow the user to continue surfing the site while that process runs.

There are plenty of tutorials about how to set this up, so that’s not what I want to talk about here.

One of the potential pitfalls of processing things asynchronously, particularly if the processing involves updating database records, is multiple records being updated at the same time. For example, one user updates a Project in a background process, and another user updates the same Project somewhere else in the app that doesn’t use a background process. We want to last update to be the one that sticks, but if both updates are happening at the same time, things could get hairy.

This is the dreaded “race conditions” issue, and luckily there’s a pretty simple fix.

On ActiveRecord - and I believe this will work with any SQL database but definitely at least on Postgres and MySQL - I can lock a specific row while editing, then unlock it afterwards, so that each edit takes place in its own little bubble.

Account.transaction do
  acc = Account.lock.find(id)
  acc.balance -= 25
  acc.save!
end

This finds an account and locks it, then updates the balance, saves, and unlocks.

This is really important when dealing with numbers, money, and balances. Let me share a parable to explain:

There is an Account with 75.

A split second later, another user in that account makes a transaction for $90.

What should happen is the second user’s transaction should be rejected for lack of funds.

What actually happens without locking is that for each transaction, the first step is that the server runs account = Account.find(id) to retrieve the account, and since this is happening before either transaction has finished, the balance on the account in both cases is 25 and the account is saved. But on the second user’s transaction, the account object that was pulled from the database still shows a balance of 90 charge from the balance and saves it, thereby allowing the transaction to go through and setting the saved account balance as $10.

Is your head spinning yet?

When we lock the account per transaction, we avoid this issue by only allowing the account to be edited on transaction at a time.

It’s a cool concept but also can be tricky to wrap your head around. Here’s a blog post I borrowed heavily from for my post. Or check out the Rails API docs.

Friday, September 11, 2015

Turbocharged custom Rails / ActiveRecord validations

My code just got a lot less janky when dealing with start and end times. Before, when I wanted to validate that a user-submitted end time came after a start time, I was doing something like this:

validate :start_time_is_before_end_time
def start_time_is_before_end_time
    unless start_time.to_i < end_time.to_i
        errors.add(:end_time, 'must come after start time')
    end
end

Converting the values to epoch time and comparing isn’t terrible, but I just found a cool way to extract this out to a custom validator to make it simpler and more readable:

# app/models/model.rb
require "active_model/sequential_validator"
validates :start_time, :end_time, sequential: true
# lib/active_model/sequential_validator.rb
class SequentialValidator < ActiveModel::Validator
    def validate record
        values = options[:attributes].map do |attribute|
           record.send(attribute)
        end.compact
        if values.sort != values
            record.errors.add options[:attributes].last, "cannot be before #{options[:attributes].first}"
        end
    end
end

True, the actual validator code is not as easy to read I don’t think, but it takes some of the burden out of the model, and it also allows reusing the sequential validation in other models.

(Thanks to botandrose and the calagator project for this cool piece of code.)

Tuesday, September 8, 2015

More readable for ActiveRecord statements using Placeholder Conditions

Here’s another readability hack for Ruby ActiveRecord code. It’s called “Placeholder Conditions.”

This:

where("start_time < :time", time: Time.now)

works the same as this

where("start_time < ?", Time.now)

The second is more terse, but if you are inserting a lot of values into the WHERE statement, then the first is nice for readability.

Source: Ruby on Rails Guides

Friday, September 4, 2015

Indifferent Access in Ruby Hashes (with ActiveSupport)

I kept seeing this “Hash with indifferent access” in open source projects, but never knew quite what it was. Turns out it’s something I use in Rails all of the time without knowing, particularly in dealing with params. It allows me to access values in a hash using either string or symbolized keys.

For example:

params['name'] == params[:name]
# => true

However, a normal Hash in Ruby does not allow this:

hash = { 'name' => 'Fred' }
hash['name']
# => 'Fred'
hash[:name]
# => nil
hash['name'] == hash[:name]
# => false

We can fix this by making this into a hash with indifferent access:

new_hash = hash.with_indifferent_access
new_hash['name'] == new_hash[:name]
# => true

The hash can also be defined/initialized with indifferent access, either by calling that method on the initial hash assignment, or by creating it using ActiveSupport (which is what the with_indifferent_access method does under the hood anyway):

hash = ActiveSupport::HashWithIndifferentAccess.new(name: 'Fred')
hash['name'] == hash[:name]
# => true

Note: When working in straight Ruby, this will not work as it’s using ActiveSupport. One would likely need to run gem install active_support and require it properly.

Source: apidock and RoR api

Tuesday, September 1, 2015

More readable value change testing in rspec

Some simple but effective rspec syntax that I just learned:

expect{Object.method}.to change{Object.count}.from(0).to(1)

I think this is fairly straightforward, but essentially it just lets you test for value changes. This is basically just a clearer way of writing expectations and would replace something like this:

expect(Object.count).to eq(0)
Object.method
expect(Object.count).to eq(1)

Check the rspec docs for more details.

Friday, August 28, 2015

Quicker and Easier headers with HTTParty

You may remember last month I showed how to retrieve just the headers in an HTTP request using the HTTParty ruby gem.

At that time, there were a couple of extra options that needed to specified in the case of redirects, otherwise on each subsequent redirect, the HEAD request would be converted to a normal GET request. This wasn’t ideal because the reason I was doing HEAD requests in the first place was to save the time it would take to retrieve the entire page and instead just find out whether the request was successful. It also didn’t make much common sense.

So I changed the gem. It now follows redirects and maintains the HEAD request across all redirects.

This is one of the reasons I really enjoy working in code. There’s this great tool that works extremely well in most cases, but there’s something slightly off about one small part of it. Rather than making a support request to some big conglomeration that may or may not read it and may or may not fix the issue, I can just jump in, make the change, and hopefully help improve the functionality for myself and, in the process, for countless others.

Wednesday, August 26, 2015

Hidden pitfalls of comparing strings in Java

I’ve been learning some Java to get into Android coding. It is certainly more verbose compared to Ruby. As a simple example (which will lead me into the topic at hand), let’s say I have a variable called word with the string “widget” stored. If I want just the first letter of the word:

# Ruby
word[0]

// Java
word.substring(0,1);

What’s more, the Ruby method above returns a normal String object that can be acted on like any other string. So, if in Ruby I wanted to check if the first letter in the word was “w”:

# Ruby
word[0] == "w"

Based on that, I figured I could do something similar in Java:

// Java
word.substring(0,1) == "w";

Fail! And it’s the worst kind of fail - it doesn’t even give an error! It just returns false, even though I know that word.substring(0,1) will return “w”.
When I tried a few combinations of things in javarepl, I got some interesting results:

String letter = word.substring(0,1);
letter == "w";
// ERROR: illegal start of expression
// = "w";
// ^

and

"w" == "w"
// java.lang.Boolean res9 = true

but

word.substring(0,1) == "w";
// java.lang.Boolean res10 = false

Really strange. My guess is that in the first example, it’s trying to assign “w” even though I’m attempting to use the equality operator. But if that’s true, I have no idea why it’s doing what it’s doing in the other two.

Just for posterity, the way to get the third example to return true like it should is to use the equals method:

word.substring(0,1).equals("w");
// java.lang.Boolean res11 = true

Friday, July 31, 2015

String conditionals on ActiveRecord callbacks

I’ve got a model for push notifications that uses Parse.com, and it sends the data to Parse on a callback:

before_create :send_to_parse

The problem is, I have a whole bunch of specs that create push notifications, and I don’t want any sent to Parse during testing. Now, I don’t have the Parse credentials accessible within the test environment, but that throws an error when it tries to send to Parse. So, what I really want is to just send to Parse when we’re not testing.

Turns out this is dead simple, albeit a little strange at first:

before_create :send_to_parse, unless: "Rails.env.test?"

I’ve used conditionals with symbolized method names before, but the string bit threw me off. However, it’s simple valid Ruby code, you can put it in a string and it will be evaluated as such.

This is straight from the docs, and I thought it was super cool.

Wednesday, July 22, 2015

Check if array contains any element of another array

I wanted to check if there were common elements in two separate arrays. Seems simple enough, but I was trying to find a way to do this without looping over both arrays in some kind each jungle:

wizard_of_oz_characters = ['tin man', 'scarecrow', 'lion']
batman_villains = ['scarecrow', 'joker', 'bane']
wizard_of_oz_characters.each do |character|
  batman_villains.each do |villain|
    return false if character == villain
  end
end

I was able to pare it down to something simpler:

wizard_of_oz_characters.any? {|character| batman_villains.include?(character) }

…but at it’s core, it’s still looping through and checking each record in sequence. Not what I was after.

Then I found a StackOverflow answer which had exactly what I wanted:

(wizard_of_oz_characters & batman_villains).empty?

This returns the intersection of the two arrays (['scarecrow']), then asks if it is empty. Perfect! And the syntax is kinda fun too.

But what is it actually doing? One of the comments on the SO answer said this is faster because it’s linear rather than quadratic, and although it has been a few years since high school Geometry, I still know quadratic is much more intensive than linear. However, I wanted to find out more.

Turns out, the & operator is treating the Arrays like Sets, an entirely different data type in Ruby. From the Ruby docs themselves, a Set is a “hybrid of Array’s intuitive inter-operation facilities and Hash’s fast lookup.”

So you get the syntax of an Array with the speed of a Hash. And you get this fun and terse syntax. I’m on board with that.

Thursday, July 16, 2015

Quick and easy HTTP headers with HTTParty

UPDATE: I changed the gem. It now follows redirects and maintains the HEAD request across all redirects.

I have a method that checks URLs submitted by the user to ensure they are valid. I don’t want to scrape the page to make sure any specific text is on there because the URLs can go almost anywhere, so I basically only care if the URL returns an HTTP 200 status.

I’m using the excellent HTTParty Ruby gem to make my external requests, and it offers a handy .head method that only returns the website headers for the request:

HTTPart.head(external_url)

However, I found out that if the requested site redirects, then subsequent requests get changed to GET, which isn’t ideal since the GET request will download the entire page’s content rather than just the headers, and is understandably slower.

Thankfully, there are a couple options that can be passed to the .head method which takes care of this:



HTTParty.head(external_url_with_redirects,
              maintain_method_across_redirects: true,
              follow_redirects: true)

Now, I get just the headers, and since all I care about is whether it was a successful request, I’m able to call .success? in my method and use the return value.

There are a few external HTTP gems out there - Net:HTTP (of which HTTParty is a wrapper), RestClient, etc - but HTTParty is my favorite so far, and easiest to work with. Check it out if you haven’t already.

Tuesday, July 7, 2015

ActiveRecord querying on Postgres array column

On a Rails project I’m working on, we have a model that has a db column of array datatype. This is one of those Postgres special datatypes that isn’t present on many other SQL databases, and there’s even some contention about whether it should be an option at all.

At any rate, this is deeply ingrained in our project currently, so I don’t want to go reinventing the wheel at this point and convert this particular column to a separate model and create another has_many/belongs_to relationship. All I want is a way to find all of the objects in this model that have an empty array in that column.

Turns out there’s no built in ActiveRecord finder for this, but the raw SQL isn’t too terrible:

Model.where("NULL = ALL(array_column_name)")

Hat Tip: https://coderwall.com/p/sud9ja/rails-4-the-postgresql-array-data-type

Wednesday, July 1, 2015

Unique objects from a three way join

I have a model that is essentially a three-way join of three models. Let’s call this model Widget. It has a user_id, account_id, and place_id. I want to make sure each of those widget objects is unique in some way - in other words, I don’t want any widget object with the same user_id, account_id, and place_id.

I should probably validate for uniqueness, but only within the confines of what is in the other columns. Here’s where uniqueness scope comes in handy:

validates_uniqueness_of :user_id, scope: [:account_id, :place_id]

Now, if we try to create a Widget with the same user_id, account_id, AND place_id as one already in the system, ActiveRecord will yell at us. But if any of those values are different from what’s already in the db, we’re good to go.

If this was going to be user-facing, I’d probably also want to add a custom error message to this, otherwise it would say something like ‘user_id has been taken’, which isn’t ideal. However, these Widget objects will be created in the background, not explicitly by users, so we shouldn’t ever see these error messages.

Now let’s say we want to control for what might already be in the db. Suppose that we didn’t find out this was an issue until a bunch of people already created duplicate Widgets. Sure, we could create a rake task to comb the db and delete the duplicates, and that would probably be a good idea at some point if we truly don’t need them. But what if for some reason we wanted duplicates to save to the db, but on certain pages only wanted to display unique Widget objects?

Running Widget.all.uniq doesn’t do anything for us, because each widget object has a unique id/primary key. So, assuming we don’t need the primary key on the page we’re displaying these widgets (and since this is essentially just a three-way join with no other attributes, I think that’s a fair assumption), we can pull all other attributes besides the primary id for all the widget objects using ActiveRecord’s select:

Widget.select(:user_id, :account_id, :place_id)

This will give us all of the widget objects in the system, but with nil values for any attributes we didn’t specify - namely, the id field. Now, since we don’t have the unique id to deal with, we can easily filter duplicates using uniq:

Widget.select(:user_id, :account_id, :place_id).uniq

Just to make it cleaner, I would probably make that a scope on Widget so I could give it a name and have it make more sense for other coders on the project.

class Widget < ActiveRecord::Base
  scope :unique, -> { select(:user_id, :account_id, :place_id).uniq }
  # other stuff in Widget class
end

Widget.unique

Bingo bango bongo.

Wednesday, June 24, 2015

Take control of your rspec test suite, Part 1

Let me tell you a little story about how I took our test suite from 25 minutes run time to just under 3 minutes while still testing all the same functionality.

A large application can generate a very unwieldy test suite. On one project I worked on, the test suite took 45 minutes to run on our CI, and when I tried to run the whole thing locally, I stopped it at the 1 1/2 hour mark when it looked like it still had a ways to go.

I can live with a suite like that for awhile, because I just run the tests that are specific to the work I’m doing. However, there are times when I’m working on something that could potentially affect several different places in the app, and I may not know exactly where those places are, so I have to run the whole suite. Waiting 45 minutes to be able to finish my feature is NOT cool, especially since that will likely have to happened a few times to ensure all tests are fixed.

On that project, I was limited with what I could do on the test suite due to budget constraints. However, on another project I worked on, our test suite took 25 minutes to run, but the project manager saw the financial benefit of trimming this number down and so let me spend some time fixing our tests.

I’ll be writing a few different posts on this topic. Step 1 is the easiest part: gathering data. Often, only a handful of tests take the longest to run, so we want to find out which of our tests are “losers” and try to refactor them into “winners.”

Thankfully, rspec gives us a command to do just that:

rspec --profile
# or rspec -p

This will run the entire suite, then list out the 10 examples that took the longest to run. If you want more than 10, you can specify the number you want as an argument, i.e. rspec -p 25.

You can also use this when running on certain test groups. So, if you wanted to find out the 17 slowest feature specs:

rspec -p 17 spec/features

Now you know the worst offenders. Stay tuned for part 2 where we delve into how to fix them up.

Thursday, June 18, 2015

Hack your Rspec setup using tags

I ran into an issue in rspec the other day where I had a before block to setup about 10 different tests, but I needed to write one more that was similar enough that it belonged in the same context but it required slightly different setup so the before block I already defined.

What to do? I could break out the existing tests into a nested context block and use the setup there, then do another nexted context block for my new test, but I really didn’t want to do that because all these tests should belong in the same context. I just wanted to skip the before block on one specific test.

Rspec tags to the rescue!

In this case, my new test was a JS test and all others were not (which is partly why the setup was different. So, the test was already tagged js: true, and in mybefore` block, I modified it like so:

before(:each) do |test|
  # Run this only on tests NOT tagged with js: true
  if test.example.metadata[:js] == nil
    # Existing setup code
  end
end

Works like a charm, and I still have all my related tests within the same context like I wanted.

Hat Tip: http://stackoverflow.com/questions/27864080/how-can-i-skip-some-setup-for-specific-rspec-tags

Thursday, June 11, 2015

Git stash is like a little mini save state

I’ve used this so many times and it has probably saved me all kinds of time, so I wanted to share.

Say you’ve just done a bunch of work on a new feature, modified 12 different files, and you haven’t committed anything yet. First of all:



But I know we’ve all done that. Now let’s say that you did all this on the wrong branch by accident. Sometimes git will let you switch branches without committing and take your work with you. I don’t know the hard and fast rules on how that works, and it seems to never work that way when I want it to.

If all of the work was in one file, it’d be simple enough to do some copypasta into the file on a new branch. Since we have workin a bunch of different files, that’s a no go.

Luckily, git gives us something called git stash.

Run git stash on all of your uncommitted work, and it will save it to a stash on your system. You can then shift to your new branch, and retrieve the stash by running git stash apply. Pretty cool!

Now let’s say you got yourself into a REAL mess. Let’s say that you did a bunch of work on the wrong branch, so you git stash-ed it, but you didn’t apply that stash to the correct branch. Then let’s say you got hungry and decided it was peanut butter jelly time. Then say you came back from lunch and did a bunch more work on the wrong branch.

You can git stash that work too, but when you go to apply all of your work (both stashes), it only applies the most recent. What happened to the first stash you made?

It’s still saved, but to access it, you have to run git stash list. This will show all of your stashes with the branch name where they were stashed from, and the most recent comment at the time of stashing. For example:

stash@{0}: WIP on damn_the_torpedoes: 240228e Merge pull request #384 from supremebeing7/jam_radar
stash@{1}: WIP on fix_thrusters: 7ed822 Merge pull request #383 from supremebeing7/add_lasers

To apply a particular stash, get the stash key (the stash@{x} at the beginning of the line) and run git stash apply {stash_key}. For example, if I want the work that I stashed on my fix_thrusters branch, I should run

git stash apply stash@{1}

Hopefully you get as much utility out of this as I have.

Tuesday, June 2, 2015

Quick and dirty nil and empty string handling in Ruby

I've run across issues with empty strings and nil values quite a bit lately - seems like mostly in relation to an API interfacing with iOS. Here are two quick tips:

To ensure that no nil values are given, I can call .to_s on any string values or values that should be strings. If one of them is nil, it will convert it to an empty string. If it's already a string, it will just leave it alone.

How about going the other way? .presence is the key. Call .presence on an empty string and it will give back nil. If the string isn't empty it will return the original string.

TL;DR:


"".presence 
# => nil 

"hey".presence 
# => "hey" 

nil.to_s 
# => ""

"hey".to_s 
# => "hey"  



Thursday, May 28, 2015

Simplifying Rails views with pluralize

"2 User(s) been updated."

This is a silly problem that I kept running into before I found out about pluralize.

Now, instead of having to do a conditional checking for number of users and printing the line based on that number, I can do this using pluralize in Rails:

pluralize(@users, 'User')

Or, if I want to use the Ruby version of pluralize (or, more accurately, the ActiveSupport version):

require 'active_support/inflector'
"User".pluralize(@users)

If @users is more than one, outputs "Users". If @users is 1, outputs "User". This is nice for when you don't want to display the number, just the pluralized word (i.e. "Users updated").

Tuesday, May 26, 2015

Enumerating in Ruby like a BOSS

The other day I wanted to run collect on an array, but I needed the indexes of the elements collected as well. Essentially, I wanted an array of hashes with the index as the key and the element as the value. I could have sloppily hacked together something like this:

my_new_array = []
my_array.each_with_index do |element, index|
  my_new_array << { index => element }
end
return my_new_array

When doing some Googling, I found out that Ruby allows enumerator method chaining - in other words, I can take an array and run something like this:

my_array.each_with_index.collect do |element, index|
  { index => element }
end

I love my collect method, so anytime I can use it, I will. And apparently, in Ruby, any enumerable can be called on any other enumerable.

Tuesday, May 19, 2015

Beware reserved ENV names in Rails

Not all environment variable names are created equal.

For example, if you are using Ruby on Rails, do not declare a VERSION environment variable, there is already one a reserved. The reserved VERSION envar is used by Rails in migrating database changes, so if it is changed at all, you will have problems when making new migrations.

That was a fun error to debug...

Wednesday, May 6, 2015

Testing CSV exports/downloads in Ruby on Rails with Capybara

As low-tech as CSV is, it doesn't appear to be going away anytime soon. So, I've run into a few different Ruby on Rails projects that want import from/export to CSV capability, and because I like tests, I wanted to make sure I could test not only that the CSV is exported but that the content of the CSV is correct.

Here's how to do this using Capybara and Rspec:

First, switch the driver to something that works (webkit or rack_test, but not selenium). To do this, you can run this within your code block:

Capybara.javascript_driver = :webkit

Just make sure to change it back to your preferred driver after you're done. Another option is to do this in your spec_helper.rb:

config.before(:each, webkit: true) do
    Capybara.javascript_driver = :webkit
end

config.after(:each, webkit: true) do
    Capybara.javascript_driver = :selenium 
    # or whatever your preferred driver is
end

Then just tag any CSV tests with the webkit: true tag.
(Thanks to Kevin Bedell on StackOverflow for this one.)

Once you get the driver configured properly, you can check the headers and the actual content of the CSV trivially:

click_on 'Download as CSV'
# Make sure the page is a CSV
header = page.response_headers['Content-Disposition']
expect(header).to match /^attachment/
expect(header).to match /filename="my_file.csv"$/

# Then check the content
MyModel.all.each do |record|
  expect(page).to have_content record.field1
  expect(page).to have_content record.field2
end

(Props to Andrew on StackOverflow for this bit.)

Thursday, April 9, 2015

Easy peasy AJAX requests, couched in a Rails / Coffeescript environment

What follows is a pretty standard POST using ajax, but I've had to do this sporadically enough that I felt the need to write it down for my own posterity. Since I'm most comfortable in Rails, the setting for this exercise will still be a Rails app.

Let's say you have a UsersController and POST route to /users. In order to POST to that route within a CoffeeScript (for example, users.js.coffeefile:

  $.ajax(
    url: '/users'
    type: 'POST'
    data: { name: 'Bob Roberts', age: '52' }
  ).done (data) ->
    // do something with data returned
    return

Inside your UsersController#create method, the params hash will have the data you submitted, so:

  params[:name]
  # => 'Bob Roberts'
  params[:age]
  # => '52'

Then, in your create method, you can do this:

def create
  @user = User.create(name: params[:name], age: params[:age])
  render json: @user
end

Fairly standard. The only thing slightly different is the render call, which will convert the object to a JSON hash and return it to the ajax POST as a data packet. That data object gets returned in the .done section of the ajax call for you to do with whatever you want.

This approach has come in handy for me on a surprising number of occasions, despite how little JS code I write on a daily basis, so it's very good to know.

Tuesday, April 7, 2015

Simple JavaScript tricks for address bar parsing

Ever wanted to get the current URL using JavaScript?

  window.location.href

You can also retrieve various pieces of it by replacing .href with .host, .protocol, or .pathname

(Thanks to CSS-tricks.com for the tips!)

Monday, April 6, 2015

Don't delete your migration files!

This is probably Rails 101 but this is something that I just had the extreme displeasure to experience, so I felt the need to comment. 

Exercise EXTREME caution when deleting a migration that has been deployed. 

This can seriously mess up your database.

I recently took over a project where the previous developer had two differently-named migration files trying to add the same column to the same table in the database, and it was messing things up. However, the first (incorrectly-named) file had already been migrated, leaving DuplicateColumn errors when trying to migrate the database when it got to the next migration. Since the first file was the one that was incorrectly named, I deleted that one. Unfortunately, that one had already been deployed to staging, so when I tried to migrate on the staging server, it still gave me a DuplicateColumn error because it saw the duplicate migration as a new migration that needed to run, and the first column was still in the schema.

Long story short (is that still possible?), I had to re-create the incorrectly-named migration file and remove the second migration file that was doing the same thing instead. Then, since I'm a teensy bit OCD and I don't like have migration files with incorrect names, I wrote a new migration to remove the column, migrated to update the schema, then deleted both migration files and created one last one that would add that needed column back into the database schema.

Needless to say, it was a huge hassle, and the moral of the story is: Be Very Careful Deleting Deployed Migrations.

Sunday, April 5, 2015

Speed up your app's delegation skills using `:includes`

My last post talked about delegating methods to a parent model using the delegate module. I want to talk about performance issues you could experience doing this, and a simple way to fix them and speed them up.

When querying databases, there's something called "eager loading" that essentially is a way for the code to pull associated objects that may be needed at the same time as pulling the main object, thereby saving a separate DB call and hopefully saving some time. I won't pretend to know exactly how this works, I just know that it's supposed to be faster to do it this way.

In my previous example, I had a Course with an associated CourseName, because I wanted to be able to create multiple Courses with the same name but different times and dates. I delegated the :name method to CourseName, so that instead of calling course.course_name.name, I can simply call course.name to achieve the same results. However, when I do that, it has to load the CourseName object on the fly, and that could result in some additional sluggishness. (Apparently, this is hotly debated whether these N+1 queries are faster or slower.)

This is where eager loading is helpful.

When you are finding a course with Course.find(params[:course_id]), throw in one additional thing to make this eager load the associated course name:

  Course.includes(:course_name).find(params[:course_id])

This helps remove the N+1 query and will hopefully help my performance. Now let's say I have a School object which has_many :courses. When I call school.courses, if I'm going to be displaying the course name as well, I'm into N+1 query land again. The easiest way to fix this is by adding it directly into the association in the School model:

class School < ActiveRecord::Base
  has_many :courses, -> { includes(:course_name) }
end

Whambo.


Hat Tip: http://blog.arkency.com/2013/12/rails4-preloading/ for the help in understanding preloading

Friday, April 3, 2015

A true leader (in Rails) knows how to delegate

When building a larger Rails app with lots of associations, I've run into an issue a few times where one object belongs to another, and I want to get the value of the parent object from the child object. This is going to get very esoteric very quickly, so let's get an example going.

Say I have a Course model with an associated CourseName (belongs_to :course_name), because I want to be able to create multiple Courses with the same name but different times and dates. Since Course does not have a name, any time I find a Course object and want to show the name, I have to call course.course_name.name. Previously, I've written a shortcut method on Course:

  def name
    course_name.name
  end

That isn't a huge issue, but if there are a lot of CourseName methods or attributes that I want to access directly from Course, it starts to be a pain having to define a new shortcut method for each.

This is where Rails' delegate module comes in very handy. Here's what the above example would look like using delegate:

class Course < ActiveRecord::Base
  belongs_to :course_name
  delegate :name, to: :course_name
end

I've delegated the name method that I would have had to define in Course to the CourseName model instead, so when I am working with a course object and I call course.name, it will look for the delegated method in the model that it was delegated to, based on the association.

This delegation stuff is pretty powerful and extendable according to the docs, so I'm looking forward to playing around a bit with all the other stuff that can be done.

Sunday, March 29, 2015

Format your Time the easy way with Rails locales

If you haven't ever used locales in Rails before, you're in for a treat. This is a super powerful feature bundled with Rails in the rails-i18n gem. The Ruby on Rails guide for it packs a lot of info to cover all types of scenarios, but I'm going to talk here about a couple very simple tweaks you can make to easily format your Date, Time, and Datetime objects consistently across your entire site.
First, this post is going to assume your app is written in English, and the instructions that follow are written specifically for that scenario, but locales work for any language, so you just need to place your code in the proper YAML file.
Let's say you want all of your Datetime or Time objects in your app formatted in the Month Date, Year - HH:MM Meridian format (i.e. June 25, 2009 - 10:24 PM). The old fashioned way is to have to use .strftime('%B %d, %Y - %H:%M %p'). Don't get me wrong, I love me some strftime, but I don't want to be having to type or copypasta that stuff every time. Here's what we're going to do instead:

  # config/locales/en.yml
  en:
    time:
      formats:
        full: "%B %d, %Y - %H:%M %p"
Then, in your views wherever you want your Time object (for example, object.created_at)to be formatted this way, instead of this:

  object.created_at.strftime('%B %d, %Y - %H:%M %p')
Do this:

  l object.created_at, format: :full
The 'l' prefacing your object is a locale method, and the Time object gets passed in as an argument, with the formatting option that you want to use. Now, if you have a couple different formats you use throughout your app, say :full, :date_only, and :time_with_zone, this makes it so much easier to use.

  # config/locales/en.yml
  en:
    time:
      formats:
        full: "%B %d, %Y - %H:%M %p"
        date_only: "%B %d, %Y"
        time_with_zone: "%-m/%-d/%y %-I:%M %p %Z"
Instead of trying to remember the alphabet soup of strftime, it is way cooler to just call your locale method with the human-readable format you want.

Saturday, March 28, 2015

Capybara tests with Rails `disable_with` on forms

Here's something that threw me for a loop for a little bit.

When using the disable_with option on form submit buttons, under the hood this is running some minimal JavaScript code, so Capybara tests have to be run as js: true, otherwise they will fail.

Wednesday, March 25, 2015

Rails' flash vs flash.now

I've seen these two things on several projects and never knew the difference. Until now!

 Boiled down to the very basics, use flash.now before a render call, and flash before a redirect_to.

  flash persists across an action, so if you use flash for a render, the flash message will show up on the rendered page AND the next page after clicking a link. Conversely, if you run flash.now on a redirect_to, you won't even see the message because the flash.now doesn't persist across requests. 

Thanks to these resources:
http://trace.adityalesmana.com/2010/10/difference-between-flash-and-flash-now-in-ruby/
http://ionrails.com/2009/09/19/flashnotice-vs-flash-nownotice/

Tuesday, March 24, 2015

Attach files and configure `delivery_method` in Rails ActionMailer

Today is a twofer!

Attachments in ActionMailer for Rails

First, I never tried sending attachments in a Rails mailer before, but it is incredibly easy. Just throw this line into your mailer method:

  attachments["screenshot.png"] = File.read("#{Rails.root}/public/images/screenshot.png")

And of course, replace the file name in the attachments hash with what you want the attachment name to be, and then replace the path in the File.read with your attachment's path.

Specify :delivery_method for individual mailer methods

This part can come in handy if you have a specific mailer method that you want to actually send in the testing environment, instead of just outputting to a file or to the log. The specific use case I have for this is when I have finicky intermittent test failures when running our test suite on my CI service (something I've talked about elsewhere). This method grabs the screenshot that was taken when the error occurred, and it emails it to the email passed in:

  def error_email(email, public_image=nil)
    attachments["screenshot.png"] = File.read("#{Rails.root}/public/images/screenshot.png")
    mail(to: email, subject: 'Capybara error', delivery_method: :smtp)    
  end

Since this is happening on my CI server and I can't look at any tmp files it creates, I need the email to actually send via SMTP, but I still want every other mailer method to deliver via the :file method because I don't want to get a boatload of emails every time the test suite runs.

Pretty nifty! Thanks to jankubr on StackOverflow for this one.

Monday, March 23, 2015

Caveat to omitting `self` in Model method calls

I wanted to add a caveat to something I stated in a previous post about leaving self out when calling methods from inside other methods in a model. This WILL give you problems if you are trying to assign values to a Model attribute.

For example, doing this:

  def change_object_name
    name = "Steve"
  end

All this is doing is setting a local variable called name equal to "Steve." If your Model has an attribute called name and you want to set it, you have to use self.name:

  def change_object_name
    self.name = "Steve"
    # Oh, and don't forget to save!
    save
  end

Sunday, March 22, 2015

Undo your last git commit

If you check my Google search history, one of the most frequent searches you'd probably see is "undo git commit." This is primarily from pulling the latest master or staging branch, making changes and committing accidentally before creating a new branch. So, I create the new branch with my new commit on it, but then I want to switch back to master or staging and nuke that last commit. Here's the very simple one-liner I use, taken directly from this extremely helpful StackOverflow answer:

  git reset --hard HEAD~1

Make SURE you have created that new branch so that you have your commit somewhere else, because this git command will completely erase your commit from the branch in which you are currently working.

Saturday, March 21, 2015

Get easy snippets in Rails views with `truncate`

Silly me, when I had a Note model that I wanted to show just a snippet of the note content with a link to view the full note, I wrote three separate methods that worked in tandem to do this. Then, I found out about truncate:

  truncate("Once upon a time in a world far far away", length: 17, separator: ' ')
  # => "Once upon a..."

  truncate("Once upon a time in a world far far away", length: 17)
  # => "Once upon a ti..."

The separator option will only truncate the text at that char, so in this case, it won't break up words, it will get to 17 characters, then find the previous space (or whatever character is specified as the separator) and truncate there. As you can see, without the separator option, it counts up to 14 and adds an ellipsis to make the total character count 17.

There are several other options to extend this that you can check out in the docs. NOTE: This can be used by default in Rails views because it's part of ActionView::Helpers::TextHelper, but must be specifically included if you want to use it elsewhere in the app.

So save yourself some time and trouble, don't be like me and start making up snippet methods when there's a perfectly good one already built!

Friday, March 20, 2015

Bash yourself multiple times

Here's a quick Bash trick. Run command line commands multiple times:

  for i in `seq #{run_how_many_times}`; do #{command_to_run}; done

Example:

  for i in `seq 10`; do rspec spec; done

This is super helpful in debugging tests with intermittent failures.

Thursday, March 19, 2015

Using `self` in Model methods

A friend recently asked me about this, and although I already knew it, I couldn't remember when I learned it, so I'm putting it in here now.

When calling another method from within a Model instance method, you don't strictly need to preface it with self:

  class Person
    def status
      ‘admin’
    end

    def admin?
      self.status == ‘admin’ ? true : false
    end
  end

This works exactly the same:

  class Person
    def status
      ‘admin’
    end

    def admin?
      status == ‘admin’ ? true : false
    end
  end

In fact, I almost never use self anymore in Model methods, except for readability purposes.

UPDATE: I neglected to mention the importance of using self when assigning Model attributes. See my new post for more explanation: http://spaghettirefactory.blogspot.com/2015/03/caveat-to-omitting-self-in-model-method.html

Wednesday, March 18, 2015

Find multiple records with ActiveRecord's Model.find

This is something cool that it took me over a year of coding in Ruby to find out. If I have a comma separated list or an array of IDs, I can find all of the records in one call:

  Model.find(ids)

Caveat: This will give the objects back in an array. However, if you want to run ActiveRecord methods on this, better to use this:

  Class.where(id: ids)

Then, you can chain methods like so:

  Class.where(id: ids).update_all(updated_at: Time.now)

Be careful! update_all does NOT run validations. But it is incredibly useful for updating several records without instantiating all of the objects. This is a straight sequel query, hence no callbacks.

Monday, March 16, 2015

present? vs any? in Rails

First, a few definitions, direct from the Ruby docs  and Rails docs:

present?
An object is present if it’s not blank?

blank?
An object is blank if it’s false, empty, or a whitespace string.

any?
Passes each element of the collection to the given block. The method returns true if the block ever returns a value other than false or nil. If the block is not given, Ruby adds an implicit block of { |obj| obj } that will cause any? to return true if at least one of the collection members is not false or nil. 

present? is a Rails method from ActiveSupport
any? is pure Ruby A few important points:

  nil.any? 
  # => NoMethodError: undefined method `any?' for nil:NilClass

  nil.present? 
  # => false

  [""].any? && [""].present? 
  # => true

  [""].any? &:present? 
  # => false

The last example is good if you need to make sure there are no blank values in an array.

 So, how do all of these measure up, performance-wise? Well, they're all pretty similar, but it seems that any? is moderately faster than present, so if you can get away with it, go for that one. However, as far as I'm concerned, when dealing with such a small performance difference, readability becomes more important, so I would personally go for whichever is more readable that still accomplishes my purposes. With arrays, that tends to be any? most of the time.

Benchmarks:

  array = (0..500000).to_a
  Benchmark.bmbm do |x|
    x.report("any with empty array:")   { 100000.times { [].any? } }  
    x.report("present with empty array:") { 100000.times { [].present? } }  
    x.report("any with stuff:")   { 100000.times { array.any? } }  
    x.report("present with stuff:") { 100000.times { array.present? } }  
  end  

                                  user     system      total        real
  any with empty array:       0.010000   0.000000   0.010000 (  0.010986)
  present with empty array:   0.010000   0.000000   0.010000 (  0.015146)
  any with stuff:             0.010000   0.000000   0.010000 (  0.008500)
  present with stuff:         0.010000   0.000000   0.010000 (  0.012448)

Monday, March 2, 2015

Discrimination in Rspec

I'm fully against discrimination in almost all its forms. I say "almost" because, when it comes to testing with rspec in Ruby, I'm fully in favor of it. Here's why: I can tag tests in rspec and run only those tests.

This has a lot of cool use cases, but I'm using it for running rspec tests in parallel on my CI service. For example:

  describe 'get averages but takes a long time', slow: true do
    it 'gets average foo' do
      ....
    end

    it 'gets average bar' do
      ...
    end
  end

Then, to run only tests tagged as "slow", run rspec with this command:

  rspec --tag slow

Another option is to have rspec automatically NOT run certain examples, such as "slow":

  RSpec.configure do |c|
    c.filter_run_excluding slow: true 
  end

Then, to run all examples:
  
  RSpec.configure do |c|
    c.filter_run_excluding slow: true unless ENV[‘ALL’]
  end

Then run rspec with this command:

  ALL=1 rspec

I can also run all tagged tests without doing any rspec configuration using this command:

  rspec . --tag type:special

Or I can run all tests EXCEPT certain tagged tests using this command:

  rspec . --tag ~type:special

Thanks to Myron Marston on StackOverflow for this nifty trick.

Thursday, February 26, 2015

Touch objects in a has_and_belongs_to_many association

On has_many relations, there is a simple way to update all associated objects - just add touch: true and the updated_at field on all associated objects will get updated. This is a major issue with Russian Doll caching, because this is was expires the cache and makes sure the page shows the most recent changes. However has_and_belongs_to_many (HABTM) does not have a :touch option. It must be done manually. So, here's a quick and easy way to do this:

  class Category
    before_save :touch_videos

    def touch_videos
      videos.touch
    end
  end

  class Video
    def self.touch
      update_all(updated_at: Time.now)
      # or, if you need validations to run for some reason
      find_each { |video| video.touch }
    end
  end

Wednesday, February 25, 2015

Handling nil values with #to_s

Occasionally, I have run into 500 server errors because there is an object attribute that is nil and I try to run a method on it. This tended to happen in my jbuilder files for returning API responses where the mobile app needed data in a certain format. Here's the simplest way to fix this:

nil.to_s 
#=> Outputs “”

Even if I wasn't getting server errors, in jbuilder files, often returning a null value in the response can be problematic for whatever app is using that response, so if there’s a chance an object attribute is nil, instead of doing an if/else, simple run #to_s on the attribute. I’m guessing this might be a slight performance hit, but probably not much more than an if/else statement would be.

Thursday, February 12, 2015

Enumerate in reverse with true indexes in Ruby

I had a problem one day where I had a list that I wanted to enumerate over, but I wanted to do it in reverse order. Easy peasy by just calling #reverse on the collection, right? Sure, except that I wanted the index as well. Oh, and I wanted the index to start with the last one instead of zero.

Now it's getting good.

I found this beauty on StackOverflow (thanks Bue Grønlund, whoever you are). To do a reverse each_with_index with the true index:

['Seriously', 'Chunky', 'Bacon'].to_enum.with_index.reverse_each do |word, index| 
  puts "index #{index}: #{word}" 
end

Output:

index 2: Bacon 
index 1: Chunky 
index 0: Seriously

Pretty nifty!

Monday, February 2, 2015

Make an array of sequential numbers in Ruby

There are lots of ways to do this, but this one is the most fun and most terse I've found:

  [*1..7]
  # => [1,2,3,4,5,6,7]

And that's Jenga.

Wednesday, January 28, 2015

How to make a ruby executable file

Thanks to Commander Coriander for this next bit. I have "borrowed" heavily from the guide there.

How to make a ruby executable file, a fairly major step in gem creation

First, create a Ruby script that will display something. Doesn't matter what, we just need to be able to test that the final executable is working. Let's call our program "awesome_sauce.rb"

Next, instead of having to type ruby awesome_sauce.rb to run our script, let's get it so we can just type awesome_sauce.rb and it infers that we want to use Ruby to run it. To do that, we just need to add the following to the very top of our script:

  #!/usr/bin/env ruby

This is called a "Bash directive" and it tells Bash what program to run our file with by asking for the current configured version of Ruby as specified by the env command. Check out man env for more info on how env works, but essentially, it will use whatever version of Ruby that's configured in your shell session. To find out which Ruby version that is, just run ruby -v

Now we need to make our script executable, so we have to give the file an execute permission. Wikipedia is great for reading all about file permissions for the uninitiated (http://en.wikipedia.org/wiki/File_permissions#Traditional_Unix_permissions). Doing that is just a simple Bash command. Assuming you're already in the same directory as your Ruby script, run this command to add execute permissions:

  chmod 755 awesome_sauce.rb

We're going to add execute permissions which will appear as an x in that line. If you check the file permissions by running ls -l awesome_sauce.rb, the output should be something like this:

  -rwxr-xr-x  1 username  staff     28 Jan  14:02 awesome_sauce.rb

The 'x' as the fourth character tells us that the file can be run directly without calling Ruby first. The following command should get our script to run:

  ./awesome_sauce.rb

It's now an executable! All that's left is cleanup, i.e. removing the prefix ./ and the suffix .rb. The suffix part is easy - just rename your file to awesome_sauce. I still do file renaming with the GUI, but here's how you can do it command-line-ninja style:

  mv awesome_sauce.rb awesome_sauce

Finally, to remove that prefix ./. The reason that is there is because every time we call a Bash program, Bash searches through a predefined list of folders looking for those programs, called the path. Your path is stored as an environment variable on your computer, and can be seen by running:

  echo $PATH

The output should be a long string of various system-critical folders, separated by colons. The one we're looking for is /usr/local/bin/, which is where any user additions should go. If that folder doesn't exist, create it:

  mkdir -p /usr/local/bin/

Now, rather than actually moving our program, let's instead create a symlink (also known as softlink or alias) within the /usr/local/bin/ folder. (To read more about symlinks, short for Symbolic link, Wikipedia is your friend.) To create a symlink, make sure you're still in the same directory as your awesome_sauce and use the ln command:

  ln -s $PWD/awesome_sauce /usr/local/bin/

The $PWD variable will expand to an absolute path to our delicious awesome_sauce.

And you're done! You've now got a fully executable awesome_sauce Ruby script. Pretty slick, friendo.

Tuesday, January 27, 2015

Speed up your ActiveRecord queries with Model.select

Say you want to display a list of all your users' names and link to their show pages. Instead of running User.all, instantiating every field of every user, there's a better way. Since you only need the name and id or slug (for the link), better to run:

@users = User.select(:name, :email)

That will instantiate user objects with just those attributes, saving memory and database query time. 

Also, brand new for Rails 4.2, you can presumably print out the fields selected by called @users.first.accessed_fields. This is primarily helpful in development mode so you know which fields you have access to. However, I couldn't get this to work locally, might need to be using master branch of Rails. Read more here: https://github.com/rails/rails/commit/be9b680

Monday, January 26, 2015

Simple bundler trick to see what gems and versions are installed

So you want to see what gems and which versions are installed for your app. Sure, you could simply look at your Gemfile.lock. Or, you can run this handy command: bundle show

Friday, January 16, 2015

Pitfalls when using Rails `render_to_string`

I spent a couple hours debugging this one and thought I should write it down:

#render_to_string needs the full file extension for templates and partials passed in, and it also needs locals defined even if the local is an exposed variable or an instance variable.

For example, the approach detailed in the previous post:

    object_details = JSON.parse render_to_string(partial: 'path/to/object/detail.json.jbuilder')

It needs locals defined in order to work properly:

    object_details = JSON.parse render_to_string(partial: 'path/to/object/detail.json.jbuilder', locals: { object: object })  

Also need to ensure if there are any nested partials within the partial being rendered to string, those partials need the file extension as well.

Thursday, January 15, 2015

'Publishing' an object and associations using serialized fields

This is one I'm pretty proud of. It's certainly not perfect, and we'll see how future proof it is, but I think with the problem I was trying to solve, it came out as a fairly elegant solution.

On our project, we had, ironically, a Project model that had all kinds of has_many associations on it. We needed a user to be able to "publish" their project and it would essentially take a snapshot of the project object and all association data at that time, and be able to server it in JSON for API calls.

I made a PublishedVersions polymorphic model with a publishable_id and publishable_type, and a serialized `details` field so it can just hold a JSON hash in the right format.

class PublishedVersion < ActiveRecord::Base
  serialize :details
  belongs_to :publishable, polymorphic: true
end

Then, when the user publishes an project, in whatever action that form goes to (:publish or :update, probably), we run

  object_details = JSON.parse render_to_string(partial: 'api/projects/detail.json.jbuilder')

to render the proper project detail response as JSON.

After that, we persist that response right into the details field of the PublishedVersion object.

PublishedVersion.create(publishable_type: ‘Project’, publishable_id: project.id, details: published_details)

Our Project class gets a has_many :published_versions, as: :publishable relation. This way, there is a history of published versions which user can view as snapshots.

If they really screw up the work-in-progress version of Project, they could revert to a previous version potentially, although this kind of functionality would be better handled by using something like paper_trail.

(The reverting process would have to be built as a separate method or class even, and it would have to find a published version by timestamp or id, and create or update all of the instances and associations. Nonetheless, the data would be in the database, so it's completely doable.)

For API calls to get the published version, since it’s already in JSON format, we don’t even need to render a jbuilder, we can simply run:

render json: object.published_versions.last.details

I made a helper method for this, #most_recent_published_version, that calls the same code.

Wednesday, January 14, 2015

Very VERY basic Rails caching

If you're doing any sort of complex caching in Rails, you're probably not going to be using these below methods too much, but they're cool to know anyway.

Rails.cache.write(‘#{cache_key}’, object)
Rails.cache.read(‘#{cache_key}’) # => object
Rails.cache.exist?(‘#{cache_key}’) # => true

NOTE: This will NOT cache associations of that object. To do that, you would need to run:

object.associations.each do |assoc|
    Rails.cache.write(‘#{assoc_cache_key}’, assoc)
    Rails.cache.read(‘#{assoc_cache_key}’) # => assoc
    Rails.cache.exist?(‘#{assoc_cache_key}’) # => true
end

You can set these caches to expire with certain options. More at http://api.rubyonrails.org/classes/ActiveSupport/Cache/Store.html

Also, make sure you're aware that if you write to the same cache key with different data, it will simply overwrite that cache. It's good practice to use the object ID as part of the cache key for doing any sort of dynamic caching, unless you're just caching static content.

Monday, January 12, 2015

A Primer on Time Zone parsing in Rails with ActiveSupport

To get time zone abbreviation (ie ‘PST’ for Pacific Time), you can call #zone method on any Time object. However, ActiveSupport::TimeZone parsing does not work with that zone format, so if you need to parse a time object by zone, better to get the full zone name. Here’s a method that does that. 

This is a helper method for views, call by itself, not on an object:

  def time_zone_name(any_time_object)
    utc_offset = time.to_s[-5..-1]
    # UTC offset example: Eastern Time == '-0500'
    # We need it in integer format -5
    ActiveSupport::TimeZone[utc_offset.gsub!('0','').to_i].name
  end

# => ‘Bogota’ (which is the same time zone as Eastern Standard Time (US and Canada)

Now you can use this time zone string to parse Time objects with ActiveSupport::TimeZone

ActiveSupport::TimeZone[“Bogota”].parse(Time.now.to_s)
# => outputs the current time with -0500 UTC offset, aka Eastern Time

Caveat: it will output that time with the abbreviation for Bogota time zone, COT. Example: Mon, 12 Jan 2015 15:50:57 COT -05:00 The time and UTC offset will be the same as for EST, and should behave similarly when parsing, but it is still something to be aware of.

Sunday, January 11, 2015

One simple way to get data from a Rails view into a JavaScript file

I had a tricky problem where there was some data from the server that was being sent to the view in query params, and I needed it in my JS file to selectively show/hide elements. Here's what I ended up doing.

In my view (HAML syntax, for the uninitiated), I am essentially creating an empty div, giving it a unique ID, and filling in data attributes with the data I need. (NOTE: start_date, start_time, and time_zone are variables defined elsewhere):

  #video-or-in-person-fields{ 'data-start-date' => start_date, 'data-start-time' => start_time, 'data-time-zone' => time_zone }

Then, in my JS file:

  start_date = $("#video-or-in-person-fields").attr('data-start-date')
  start_time = $("#video-or-in-person-fields").attr('data-start-time')
  time_zone = $("#video-or-in-person-fields").attr('data-time-zone')

Whammy.

Saturday, January 10, 2015

Handling datetime in JavaScript (or more accurately, CoffeeScript)

Working with Date, Time, and DateTime seems to be pretty awful in any language, but compared to Ruby and ActiveSupport, doing it in JS or Coffee is awful. You can get libraries that make it a little easier to work with (I believe Moment.js is one such that can be very helpful), but for simple formatting things, it's easier and more lightweight to just write your own functions.

 This gives today’s date in YYYY-MM-DD format:

  date_today = ->
    today = new Date()
    dd = today.getDate()
    mm = today.getMonth() + 1
    yyyy = today.getFullYear()
    if dd < 10
      dd = '0' + dd
    if mm < 10
      mm = '0' + mm
    today = yyyy+'-'+mm+'-'+dd
    return today

This gives the current time in HH:MM:SS -0800 format, where -0800 is the timezone offset from GMT, and the HH are displayed in 24 hour time:

  time_now = ->
    right_now = new Date()
    hh = right_now.getHours()
    mm = right_now.getMinutes()
    ss = right_now.getSeconds()
    time_zone = right_now.toString().split(':')[2].substr(6, 5)
    if time_zone == ""
      time_zone = "UTC"
    right_now = hh+':'+mm+':'+ss+' '+time_zone
    return right_now

Friday, January 9, 2015

Very VERY basic Vagrant commands for a n00b

This is nothing that can't easily be found in the docs, but it was new to me:

  vagrant up

This uses a Vagrantfile to start up a virtual machine (such as starting up an Ubuntu environment using VirtualBox)

  vagrant ssh

This will SSH into the virtual machine, but first you need to ensure that SSH keys are configured properly. These can be passed in by setting this in the Vagrantfile:

  config.ssh.forward_agent = true

Thursday, January 8, 2015

Joining two join tables in Rails

Joining data from two join tables in Rails is gross, but sometimes necessary.

Let’s say I have a join table items_categories and a join table items_groups. I want to get all items that are in the same category and the same group, by category and by group ids. Here's how I did it:

  Item.joins(:items_groups).joins(:items_categories). 
       where('items_categories.category_id = ?', category_id).
       where('items_groups.group_id = ?', group_id)


UPDATE: Since posting this, we have changed how we handle this and made a model to holds all three IDs so there is a three-way relation. This seems to be a better approach than the above, but it was fun making all those joins anyway.

Wednesday, January 7, 2015

Reload stale objects in finnicky Rails rspec tests

I have had plenty of times where an rspec test was failing because an object was still showing an old value after an update. This seems to happen most often in Capybara. I know I'm not technically supposed to be checking object data in Capybara tests, just checking what's actually seen on the page, but there are some times where I need to be extra sure, or where the data being updated isn't showing on the page.

In rspec, call #reload on an object if it has changed in the database in order to sync and get the most recent changes.

NOTE: The object must have an ID, because under the hood it is just running
object = Object.find(object.id)

object.name # => 'Frank'
object.update(name: 'Tank')
object.name # => 'Frank'
object.reload
object.name # => 'Tank'

Tuesday, January 6, 2015

Adding error messages in custom Rails validate methods

If you've ever needed custom validators in Rails, this is what you need in your methods when something doesn't pass a validation:

  errors.add(:base, 'A star count score must be within the range of 0 to 5.')

This will add that error message to object.errors If you tweak it slightly to this, it becomes more extensible:

  errors.add(:star_count, 'score must be within the range of 0 to 5.')

You can call object.errors.full_messages.each do |message| and it will basically output this: “#{:star_count.to_s.capitalize} score must be within the range of 0 to 5.”