Linked contentRepeats

Respect time zones: Use Time.current and Time.zone.parse

Reading the current time

Don't use Time.now as it's broken when using time zones. \
Instead, use Time.current, DateTime.current or Date.current (the latter actually not being different, but just use it for good measure).

Parsing strings

Don't use Time.parse as it only gives you a Time object.
Use Time.zone.parse instead for a TimeWithZone.

Ruby: Don't a add return in ensure

This method won't throw an error:

def a_method
  raise
ensure
  return :something
end

it will in fact return :something

So please proceed with care :)

DateTimes are Dates, beware

Given:

datetime = DateTime.now
date = datetime.to_date #or Date.today

will assert:

datetime.is_a? Date == true
datetime.is_a? DateTime == true
datetime.instance_of? Date == false
datetime.instance_of? DateTime == true

In case you have a table and a model like:

create_table :event do |t|
  t.date    :day
  t.string  :description
end
class Event < ActiveRecord::Base; end

And you say:

event = Event.new(:day => '2013-03-22')

Rails will convert the supplied value for day to the type of the database field,...

Profiling Ruby with ruby-prof

require 'ruby-prof' # you don't need this if you have ruby-prof in your Gemfile

You can set one of the things you want to measure by using (default is PROCESS_TIME most useful ones are PROCESS_TIME, MEMORY, CPU_TIME):
RubyProf.measure_mode = RubyProf::PROCESS_TIME
RubyProf.measure_mode = RubyProf::WALL_TIME
RubyProf.measure_mode = RubyProf::CPU_TIME
RubyProf.measure_mode = RubyProf::ALLOCATIONS
RubyProf.measure_mode = RubyProf::MEMORY
RubyProf.measure_mode = RubyProf::GC_RUNS
RubyProf.measure_mode = ...

has_defaults issues

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

class Order
  has_defaults :items => []
end

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

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

has_defaults :items => proc {[] }

When
Consider do...

Cleaner Rspec

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

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

Do:
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
end

   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'
  [1,2,3]
end

...

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

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

Property.listable.for_2_or_more_guests.best_10_properties

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...
This website uses short-lived cookies to improve usability.
Accept or learn more