27 cards

has_defaults issues

The object returned by has_defaults apparently is the same between multiple object creations.
Consider this scenario:

class Order
  has_defaults :items => []

o1 = Order.new
o1.items #=>> []
o1.items << item
o1.items #=>> [item]

o2 = Order.new
o2.items #=>> [item]

So, now o2.items is not empty by default because we modified the same object in has_defaults

When using has_defaults on a model, consider using it in the following way:

has_defaults :items => proc {[] }

Consider do...

Killing wkhtmltopdf during cucumber

wkhtmltopdf hangs on mac during cucumber unless we click on it. The main reason is with the version we use which is 0.11.0_rc1 and in out app/bin we have another version and it is a known issue with these versions. The fix is to go to 0.9.9, to downgrade the version we installed earlier using brew:

* brew uninstall wkhtmltopdf
* brew update
* brew versions wkhtmltopdf
* if you see output like 
*         `0.9.9    git checkout 6e2d550 /usr/local/Library/Formula/wkhtmltopdf.rb`
           then `cd /usr/local`
* g...

To avoid using bundle exec or creating rvm gemsets

  1. Add to the end your .bash_profile export PATH="./vendor/bundle/bin:$PATH"
  2. Also add alias bi="bundle install --path vendor/bundle --binstubs=vendor/bundle/bin"
  3. Then to bundle install next time just use bi

Now no more bundle exec before any rake, cap, spec or anything else :)

Cleaner Rspec

When simply checking equality or truthiness then
Instead of:
it "should have role set to admin" do
@user.role.should eql('admin')

it "should be valid" do
  @user.valid?.should be_true

it { @user.role.should eql('admin') }
it { @user.valid?.should be_true}

Try to stick to one expectation per test block, diverge in exceptional circumstrances, so instead of:
describe "#some_method" do
before(:each) do
@object = Class.new

   it "should have attributes set" do


Method return value should always be of same type

One of the main source of bugs and complexity in the code is when a functional method (that we expect to return a value) return different values under different circumstances.

For example, we ruby programmers have a bad habit of returning nil from a method when certain condition is not fulfilled else return an Array or Hash. That just makes the calling code unnecessary complex and error prone because then it has to do different checks.

Bad Practice:

def bad_method(param)
  return unless param == 'something'


Caching: don't use content_for, it won't work

Do not use content_for inside a cached view fragment. It won't work because Memcache will just output whatever is in the cache, and not execute such commands.

Linked content

Creating a gem in lib folder

Go to lib folder and use bundler to generate main files for a gem:

$ bundle gem test_gem

      create  test_gem/Gemfile
      create  test_gem/Rakefile
      create  test_gem/LICENSE
      create  test_gem/README.md
      create  test_gem/.gitignore
      create  test_gem/test_gem.gemspec
      create  test_gem/lib/test_gem.rb
      create  test_gem/lib/test_gem/version.rb
Initializating git repo in /path/to/webapp/HouseTrip-Web-App/lib/test_gem

cd in to created directory

$ cd test_gem/


ActiveRecord::NamedScopes (2.3.x) obtaining the SQL conditions

It's a good pratice to chain several named scopes like:


Now, to make the lesson more valuable let's assume the following code:

Property.scoped(:conditions => "foo = 2").scoped(:conditions => "foo2 IS NOT NULL")

Next, if you want to be able to fetch the underlying conditions scope generated by ActiveRecord. You must do this:

Property.scoped(:conditions => "foo = 2").scoped(:conditions => "foo2 IS NOT NULL").scope(:find)
# => {:conditions => "(foo = 2) AND (foo2...

Git Branch naming

This is how we name branches :

  • <team>/<story>-<id> (features)
  • fix/<team>/<story>-<id> (bugs)

story is an dash-delimited version of the story name, and id the Pivotal story number.

Examples :

  • supply/belvilla-naming-1234567
  • fix/tripadvisor/property-syncing-3256674
  • integration/geo/boroughs
This website uses short-lived cookies to improve usability.
Accept or learn more