Rails tips
Found these on HabraHabr today. Here are some tricks I found usefull.
Private methods are not actually private
Let us have class:
class Moo
private
def self.foo
puts 'foo'
end
end
Here, class method foo
is not private:
Foo.foo
=> 'foo'
Instance with params
Oftenly there is a need to create a class instance and set it some params (or, maybe, call some methods on it). It’s done usually like this:
moo = Moo.new
moo.foo = 'foo'
moo.bar
This can be shortened with the use of `tap` method:
moo = Moo.new.tap { |a| a.foo = 'foo'; a.bar }
Yet, it is more ruby-convenient and ruby-style to do it with the initialization block:
class Moo
attr_accessor :foo
def initialize(&block)
yield self if block_given?
end
def bar
puts "bar!"
end
end
moo = Moo.new do |a|
a.foo = 'foo'
a.bar
end
puts moo.foo
Or even like this:
class Moo
def initialize(&block)
instance_eval &block if block_given?
end
def moo(val = nil)
@moo = val unless val.nil?
@moo
end
def bar
puts "bar!"
end
end
a = Moo.new do
moo 'moo~!'
bar
end
puts a.moo
Code-dependent migrations
When you have your migrations using your code, for example, like this:
class CreateDataVolumes < ActiveRecord::Migration
def up
Data::VOLUMES.times do |volume|
create_table "data_#{volume}" do |t|
# ...
end
end
end
end
you then have a problem when updating your code. In our example, if you remove the constant Data::VOLUMES
, you will have to either manually search for all the usages of this constant, or have a really intelliJent IDE ;)
Rather than using your existing code, stub it and copy-and-paste all migration-dependent code to the stubbing class:
class CreateDataVolumes < ActiveRecord::Migration
class Data < AR::Base
VOLUMES
end
def up
Data::VOLUMES.times do |volume|
# ...
end
end
end
Example with constant is rather stupid, whilst you may have some more critical code.