Skip to content

Instantly share code, notes, and snippets.

@mepatterson
Created July 25, 2012 13:10
Show Gist options
  • Select an option

  • Save mepatterson/3176111 to your computer and use it in GitHub Desktop.

Select an option

Save mepatterson/3176111 to your computer and use it in GitHub Desktop.
common refactorings
# NOTES
# - many of my style changes reflect the excellent Github Ruby Style Guide
# https://github.com/styleguide/ruby/
# - convention for naming Time-based db fields is xxxx_at, Date-based is xxxx_on
# - naming methods find_by_blah_blah_blah is old, Rails 1-ish. Newer convention is just simple names
# and scoping, so you can do things like: user.named('Bob').with_children(2)
# ( as opposed to: user.find_by_name_and_children('Bob', 2) )
# - don't indent methods after a protected or private call. this is something of a matter of style
# preference, but the most common preference is no indent
# ANTI-PATTERNS / ANTI-CONVENTIONS
if !thing
if other_doodad
a = 4
end
end
# Unnecessary nesting. Just rewrite as =>
a = 4 if !thing && other_doodad
# --------------------------------------------------------
a = some_method
if !a
a = 4
end
# Ruby Convention =>
a = some_method || 4
# --------------------------------------------------------
some_method_that_sets_A_earlier
# ... bunch of extra code
unless a
a = 4
end
# Ruby Convention =>
a ||= 4
# --------------------------------------------------------
def whatsit
a = some_method
if a
a.do_something
else
raise "Could not do the thing."
end
end
# Ruby Convention (see `Refactoring Ruby` by Fields/Harvey/Fowler) =>
def whatsit
raise "Could not do the thing." unless a = some_method
a.do_something
end
# --------------------------------------------------------
def whatsit
a = some_method
if a
a.do_something
else
false
end
end
# Ruby Convention (see `Refactoring Ruby` by Fields/Harvey/Fowler) =>
def whatsit
return false unless a = some_method
a.do_something
end
# --------------------------------------------------------
FancyModel.find_by_foo_and_bar(a, b)
FancyModel.find_all_by_foo_and_bar_and_baz(a, b, c)
FancyModel.find_by_id(widget_id)
# Newer Rails Conventions =>
# (NOTE: Rails 4 will deprecate find_all_by_* and find_by_* methods!)
FancyModel.where(foo: a, bar: b).first
FancyModel.where(foo: a, bar: b, baz: c)
FancyModel.where(id: widget_id).first
# in the second case, you probably don't want .all() at the end because that will
# cause it to return an array of results, rather than an iteratable query scope, which
# tends to be more useful/performant, especially when the table gets big
# --------------------------------------------------------
# in a User model method
def find_widgets_by_title_and_platform
Widget.find_all_by_user_and_title_and_platform(self.id, title, platform)
end
# Newer Rails Conventions =>
def find_widgets_by_title_and_platform
# you already have an association with widgets on this User class,
# so just use thatand add some additional query restrictions
widgets.where(title: title, platform: platform)
end
# --------------------------------------------------------
# PROBLEM: cobbling together a big SQL statement by creating two different methods to
# account for the possibility of an optional extra restriction on the query...
# SOLUTION: use one method, and take advantage of scopes and scope-chaining instead:
def get_entitlements(title, args = {})
scope = self.entitlements.
select('entitlements.string_identifier, entitlements.payload, entitlements.consumable,
user_entitlements.consumable_amount, user_entitlements.consumed,
user_entitlements.id AS user_entitlement_id')
# you're not required to pass args[:platform] to this method, but if you do, this next line
# adds an additional restriction to the final SQL
scope = scope.where(platform: args[:platform]) if args[:platform]
scope = scope.where(title: title).not_fully_consumed
scope
end
# --------------------------------------------------------
if a == 1
b = 3
else
b = 'joe'
end
# this is a good place for a ternary =>
b = a == 1 ? 3 : 'joe'
# --------------------------------------------------------
f = 0
frogs = Frog.get_the_frogs
if frogs && frogs.count > 0
f = frogs.count
end
# use the .try() method
# try() returns nil if the method returns nil or false, and can be chained
f = Frog.try(:get_the_frogs).try(:count) || 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment