Extract ActiveRecord Scope Method

Peer review today lead to a great refactoring opportunity. The pull request centered around allowing signed in site administrators to view unpublished blog posts.

Original

My goal here is to only have the published scope apply if the current_user is not an administrator in both the index and blog_post actions.

class BlogController < SiteController

  def index
    @blog_posts = blog.blog_posts.published
  end

  def blog_post
    @blog_post = blog.blog_posts.published.friendly.find(params[:id])
  end

  private

  def blog
    current_site.blog
  end
end

Optimize Rails Database Queries with Bullet and RSpec

Bullet is a gem that helps increase your application’s performance by reducing the number of queries it makes.

The README describes how to use the gem in Development but makes no special mention of how to use it in test with RSpec.

Searching through the gem’s issues I discovered that you can use the following settings before calling visit to have Bullet raise an exception if an infraction is detected.

  Bullet.enable = true
  Bullet.raise = true

You could go a step further and update the rails_helper to allow for easier usage

  # spec/rails_helper.rb

  config.before :each, bullet: true do
    Bullet.enable = true
    Bullet.raise = true
  end

  config.after :each, bullet: true do
    Bullet.enable = false
    Bullet.raise = false
  end

Project Euler – Problem 7

I recently applied to gSchool. The code I submitted was my answer to Problem 7 at Project Euler:

By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13. What is the 10,001st prime number?

This was a fun problem to work on. Initially the method I wrote to test if a number (x) is prime involved testing each number that made up x. It resembled something like this:

def prime? number
  return false if number == 0 || number == 1
  integers = *(2..number)
  integers.each do |i|
    return false if number % i == 0
  end
  true
end

rbenv install gems fails with permission error

Helping a new dev setup their machine today with rbenv when trying to bundle I ran into this error:

ERROR:  While executing gem ... (Gem::FilePermissionError)
You don't have write permissions for the /Library/Ruby/Gems/2.0.0 directory.

Thankfully I already dealt with this before and referenced it as a comment to a question on StackOverflow. For my own future reference I will list the solution here as well.

You need to correct your paths

To determine if this fix will work run the following:

which gem

This should output a directory you do not have permissions to:

/usr/bin/gem

To fix this perform the following steps.

  1. Determine the path you need to copy to your profile:

    rbenv init -
    

    The first line of the output is the line you need to copy over to your profile:

      export PATH="/Users/justin/.rbenv/shims:${PATH}" #path that needs to be copied
      source "/usr/local/Cellar/rbenv/0.4.0/libexec/../completions/rbenv.zsh"
      rbenv rehash 2>/dev/null
      rbenv() {
        typeset command
        command="$1"
        if [ "$#" -gt 0 ]; then
          shift
        fi
    
        case "$command" in
        rehash|shell)
          eval `rbenv "sh-$command" "$@"`;;
        *)
          command rbenv "$command" "$@";;
        esac
      }
    
  2. Copy the path to your profile and save it

  3. Reload your profile (source ~/.zshenv for me)

  4. Run rbenv rehash

Now when you run which gem you should get a local path that you have permissions to:

/Users/justin/.rbenv/shims/gem

Look and Say Sequence

Had some fun recently coming up with a solution to generate any element of the Look-and-say sequence. The sequence was introduced and analyzed by John Conway. Here is an example of the sequence:

1, 11, 21, 1211, 111221, 312211, 13112221, 1113213211, ...

The best way to explain the sequence is through examples:

1 "one one" -> 11 "two ones" -> 21 "one two, one one" -> 1211, etc

This is a sequence used by Google during interviews. They ask for a method using recursion that takes in n, where n represents the n’th element appearing in the sequence, that returns the entire sequence to that point.

For example:

foo(4)
[1, 11, 21, 1211]

Here is the solution I came up with:

def look_and_say(n, x = "1", to_return = ["1"])
  if n == 1
    return to_return.map{|i| i.to_i}
  end
 
  if n > 1
    x = get_next_element(x)
    to_return << x
    return look_and_say(n-1, x, to_return)
  end
end
 
def get_next_element(x)
  current_digit = x[0]
  count = 0
  to_return = ""

  x.chars.each do |i|
    if i == current_digit
      count += 1
    else
      to_return = "#{to_return + count.to_s + current_digit}"
      current_digit = i
      count = 1
    end
  end
  to_return = "#{to_return + count.to_s + current_digit}"
  return to_return
end