Introducing Gemrat: Add Gems From the Command Line

| Comments

I published a gem earlier this week which allows developers to add gems to their Gemfile from the command line. The utility of Gemrat lies in it’s ability to grab the latest version of a gem and lock it into your Gemfile.


Example

$ gemrat sinatra

#=> gem 'sinatra', '1.4.3' added to your Gemfile.
#=> Bundling...

$ gemrat rspec

#=> gem 'rspec', '2.13.0' added to your Gemfile.
#=> Bundling...

Github Page


Inspiration

Lately I’ve been taking a service oriented approach to developing software. This means that I build smaller apps which depend on each other rather than having a huge monolithic codebase.

This approach lends itself to reusability, polyglot programming, and it gives me more chances to implement lessons learned from previous applications.

The service oriented approach also carries some debt. I’m often wrangling dependencies as I rebuild infrastructures. Developers working on monolithic apps with lots of legacy code can go days or weeks without adding dependencies. This is usually not the case in service oriented architectures.

The manual process of adding gems usually involves searching for the latest version of a gem then adding the gem and it’s version to the Gemfile. This process calls for a browser and text editor.

The same result can now be accomplished by running $ gemrat gem_name from your command line.

I use this tool on a daily basis. Solving my own problems and sharing solutions with the world is extremely gratifying work.

Enjoy!

Backup a S3 Bucket

| Comments

You can use Amazon Glacier. Here are the steps in summary:

  1. Open your bucket

  2. Click “properties”

  3. Click “Lifecycle”

  4. Click “Add Rule”

  5. Click “Move to Glacier”

  6. Fill out the rule form

  7. Apply the changes

More details here.

Sinatra With Puma

| Comments

Here’s a basic pattern for running Sinatra with Puma.

config.ru

1
2
require './app'
run Sinatra::Application

Gemfile

1
2
gem "sinatra"
gem "puma"

app.rb

1
2
3
4
...
require 'sinatra'
configure { set :server, :puma }
...

The next time that you run ruby app.rb, it will use Puma instead of WebBrick.

Sidekiq & Sinatra

| Comments

“Please point sidekiq to a Rails 3 application or a Ruby file to load your worker classes with -r DIR|FILE.”

I received this error while attempting to use Sidekiq in a Sinatra app. To solve this problem, use the -r option to point Sidekiq to your main Sinatra file.

1
2
3
...
`sidekiq: bundle exec sidekiq -r ./app.rb`
...

The -r option is also used by pry to preload dependencies.

pry -r ./app.rb gives you access to all our your methods in app.rb without the need to require it via console.

Curl Follow Redirects

| Comments

I was building a system which relied on URLs that were frequently redirected. Curl does not automatically redirect when it receives a 302 response.

Use curl http://www.example.com --location to follow URL redirects.

Copy to Shared Clipboard (Mac + Vim + Tmux)

| Comments

I had clipboard support with vim before adding tmux to my workflow.

Tmux copying does not share your clipbaord by default. You can add support by using tmux pasteboard.

Follow the instructions in the README. It has worked great so far.

Sidekiq Ec2 Elastic Beanstalk

| Comments

I didn’t see a straightforward way to setup Redis on a box built using Elastic Beanstalk so I decided to go with Redis hosting.

I setup Sidekiq to use an external Redis database. You have to configure both the client and the server for Sidekiq to work this way.

1
2
3
4
5
6
7
8
9
10
11
...

Sidekiq.configure_server do |config|
  config.redis = { url: '...', port: 9999, namespace: 'name', auth: "..." }
end

Sidekiq.configure_client do |config|
  config.redis = { url: '...', port: 9999, namespace: 'name', auth: "..." }
end

...

For more information on configuring Sidekiq, check out the advanced options docs.

Ruby Block Percent Matching

| Comments

I use the % key to switch between do-end statements at work. This feature came with a group of plugins that I share with my co-workers.

I’ve tried to implement it on other machines but haven’t been able to trace the source of it until today.

matchit accomplishes block switching. This is particularly useful when dealing with specs.

AngularJS - Unexpected Request: No More Request Expected

| Comments

I had this issue earlier, here is how I solved it.

Jasmine spec runner was returning ‘Error: Unexpected request: GET /locations/1 No more request expected.’ I stubbed the call by specifying the action (GET) and the path (‘locations/1’). If you are relying on the response data in your test then return the appropriate JSON object(s) instead of an empty array.

...
beforeEach inject(($controller, $rootScope, $httpBackend, $location) ->
  ...
  $httpBackend.whenGET('/locations/1').respond([])
  ...
)
...

AngularJS - Force Page Reload

| Comments

I’m building an AngularJS app with Rails 4 as an API and router. Using Rails for routing causes problems as users follow links, controller code on different pages isn’t being loaded. To solve this problem, I force page reloading by adding target=_self to links.

Haml example:

%a(href="/projects/{{project.id}}" target="_self") {{project.name}}

Ruby Hash - Get Dot Operator Access to Values

| Comments

Yesterday I ported some existing code to a different gem. Instead of returning objects, the new gem returns hashes. To stave off a major refactor, I casted each hash to an OpenStruct which allows you get hash values with dot notation.

house = {}
house["bedrooms"] = 5
house = OpenStruct.new house
house.bedrooms #=> 5

Rails 4 - Add References Migration

| Comments

I wanted to add a foreign key to an existing table using Rails’ references feature but this was not an option for existing tables. The good news is that Rails 4 makes it possible.

I prefer references because it allows you to be lazy by automatically adding the foreign key and index.

$ rails g migration AddUserRefToProducts user:references

This migration will add a user_id column to your products table and index it.

Control P - Ignore Vendor Files

| Comments

I installed my project’s dependencies locally while debugging. It didn’t take long to notice that control-P would pick these files up while fuzzy searching. This rendered control-P useless as it presented me with gems that I didn’t care about editing.

My solution was to instruct control-P to ignore files in the vendor directory by adding this line to the .vimrc file:

set wildignore+=*/vendor/*

Rails Console on an AWS Instance

| Comments

  1. ssh into the machine
  2. cd ../../var/app/current
  3. rails console

Dope Icons

| Comments

I came across iconmonstr yesterday while searching for icons to use in my new app. I decided to go with a set instead but they definitely had some cool stuff.

Using SCSS @extend

| Comments

This is a super useful method. Most developers tend to use SCSS just like CSS but there are tons of possibilities in this extension of CSS.

Yesterday I decided to invest some time in refactoring my stylesheets to take advantage of this power. A common pattern that I developed involved the @extend method.

Use Case

Imagine that you need to display profits and losses. You have two classes for each group which are very similar except for the text color.

@extend allows you to abstract common attributes and focus on what’s unique about each class.

CSS

1
2
3
4
5
6
7
8
9
10
11
12
13
.loss {
  font-size: 1.5em;
  letter-spacing: .1em;
  font-family: "HelveticaNeue-Light";
  color: red;
}

.profit {
  font-size: 1.5em;
  letter-spacing: .1em;
  font-family: "HelveticaNeue-Light";
  color: green;
}

SCSS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.metric {
  font-size: 1.5em;
  letter-spacing: .1em;
  font-family: "HelveticaNeue-Light";
}

.loss {
  @extend .metric;
  color: red;
}

.profit {
  @extend .metric;
  color: green;
}

This helps a lot when prototyping UIs. I no longer need to jump around my stylesheet to update properties. I can simply modify the extended class in most cases.

Rails + Factory_Girl - Create Factory Command for Models

| Comments

rails g factory_girl:model Post title:string body:text

This is great for retroactively generating factories for models that existed before you started using factory_girl.

Testing Angular Filters

| Comments

Yesterday I wrote about making my first filter for AngularJS. This morning I created a test for it. Here’s the pattern that I followed.

index.html.haml
1
2
3
4
5
6
7
!!!
%html(ng-app="ExampleApp")
  %head
  %body
    .row-fluid
      %span(ng-bind-html-unsafe="(1 > 2) | whatAmI")
      %span(ng-bind-html-unsafe="(1 < 2) | whatAmI")
controller.js.coffee
1
2
3
4
5
6
7
8
app = angular.module("ExampleApp", [])

app.filter "whatAmI", ->
  (statement) ->
    if statement
      "<span class="answer-true">I'm true</span>"
    else
      "<span class="answer-false">I'm false</span>"
controllerSpec.js.coffee
1
2
3
4
5
6
7
8
9
10
11
12
#= require_tree ../../app/assets/javascripts
#= require angular-resource
#= require angular-mocks

describe "whatAmI Filter", ->
  beforeEach angular.mock.module("ExampleApp")

  it "returns I'm true if the expression is true", inject((whatAmIFilter) ->
    expect(whatAmIFilter(true)).toBe "<span class="answer-true">I'm true</span>")

  it "returns I'm false if the expression is false", inject((whatAmIFilter) ->
    expect(whatAmIFilter(false)).toBe "<span class="answer-false">I'm false</span>")

Notes

AngularJS - Return HTML | Haml With Filters

| Comments

I wrote my first AngularJS filter today. I needed to render HTML although I used Haml for templating and it was my first time implementing the ng-bind-html directive.

Here’s a pattern that illustrates what I achieved. I’m using a simple example to illustrate the powerful concept of filtering.

controller.js.coffee
1
2
3
4
5
6
7
8
app = angular.module("ExampleApp", [])

app.filter "whatAmI", ->
  (statement) ->
    if statement
      "<span class="answer-true">I'm true</span>"
    else
      "<span class="answer-false">I'm false</span>"
index.html.haml
1
2
3
4
5
6
7
!!!
%html(ng-app="ExampleApp")
  %head
  %body
    .row-fluid
      %span(ng-bind-html-unsafe="(1 > 2) | whatAmI")
      %span(ng-bind-html-unsafe="(1 < 2) | whatAmI")

The first filter returns I'm true.

The second filter returns I'm false.

Notice that curly brackets are not used in the ng-bind-html statements.

Helpful Links:

Test Is Not a Module (TypeError)

| Comments

You most likely have a model called test.

Remove it with:

$ rails destroy model test

I ran into this issue after coming into a project where the client-code was developed first. An unused test model was created by the previous pair. As I began writing tests for the app, this test model caused a namespace conflict.