Notes posted by Oleg
RSS feed
Doesn't output into STDOUT
Oddly enough it runs a rake task without any sort of output. To get around it you can simple substitute it with:
puts run('rake your_task')
Unless somebody has a better idea?

Looking for documentation of helper methods like: template, directory, file, etc?
Well, it’s not here. For Rails 3 they are part of Thor::Actions

If you need to pass a value
In the above example ‘value’ happens to be either true or false depending if the option was passed in or not. If you wish to capture an actual value you’ll want something like this:
def add_options!(opt) opt.on('-option=value') { |value| options[:option] = value } end

Doesn't handle nested hashes
If you pass something like this:
http.set_form_data({:a => {:b => :c}})
it will completely mangle the value. So don’t use it.

Careful when updating foreign key directly
Seems when you change key directly it doesn’t update association automatically.
>> chicken = Chicken.first >> chicken.head => old_head >> chicken.head_id = new_head.id >> chicken.head => old_head
Easy (stupid?) way to fix it:
class Chicken def head_id=(value) self.head = Head.find_by_id(value) end end

define_method with parameters
Just to be clear, you can do this:
define_method(:my_method) do |foo, bar| # or even |*args| # do something end
This means same as:
def my_method(foo, bar) # do something end
If you want to define method with parameters that have default values, you need to get a bit more creative and do something like this:
define_method(:my_method) do |foo, bar| bar ||= {} # do something end

cattr_accessor_with_default
Class attribute assessors are neat if you want to set up modifiable constant-like varibles. This is how you’d normally set it up:
module MyPlugin class Conf @@awesome_level = 'huge' cattr_accessor :awesome_level end end
Then you can call and modify it like this:
>> MyPlugin::Conf.awesome_level => 'huge' >> MyPlugin::Conf.awesome_level = 'massive' >> MyPlugin::Conf.awesome_level => 'massive'
If you have a pile of those accessors I’d do something like this (there might be a better way, but it works):
module MyPlugin class Conf def self.cattr_accessor_with_default(name, value = nil) cattr_accessor name self.send("#{name}=", value) if value end cattr_accessor_with_default :awesome_level, 'huge' cattr_accessor_with_default :speed_level, 'insane' cattr_accessor_with_default :indifferent_level cattr_accessor_with_default :craziness_level, 'nuts' end end
This way you declare accessor and it’s optional default value on the same line


Find random record
It’s as simple as:
Things.first(:order => 'RAND()')
Of course depending on your database it could be ‘RANDOM()’ or something similar.

Handy shorthand for array manipulation
You may write something like this:
>> ['a', 'b', 'c'].collect{|letter| letter.capitalize} => ["A", "B", "C"]
But it looks so much nicer this way:
>> ['a', 'b', 'c'].collect(&:capitalize) => ["A", "B", "C"]

HTML entities in options
Unfortunately everything is escaped with ERB::Util#html_escape. Your only option is either manually construct options or compeletely overwrite this method.

Array clustering
Sometimes you don’t want to mangle sequence of an array and just want to group adjacent values. Here’s a nice method to do so (drop it in your initializers directory or something):
module Enumerable # clumps adjacent elements together # >> [2,2,2,3,3,4,2,2,1].cluster{|x| x} # => [[2, 2, 2], [3, 3], [4], [2, 2], [1]] def cluster cluster = [] each do |element| if cluster.last && yield(cluster.last.last) == yield(element) cluster.last << element else cluster << [element] end end cluster end end
Similarly you can do the clustering on more complex items. For instance you want to cluster Documents on creation date and their type:
Document.all.cluster{|document| [document.created_on, document.type]}

Take care when writing regex
When you want to validate a field for a continuous string you’d probably write something like this (if it’s really early in the morning and you didn’t have your coffee yet):
validates_format_of :something => /\w/
At the first sight it looks like it’s working because something = “blahblahblah” is valid. However, so is this: something = “blah meh 55”. It’s just that your regex matched a substring of the value and not the whole thing. The proper regex you’re looking for is actually:
validates_format_of :something => /^\w$/

String#match will match single token only
>> s = “{{person}} ate {{thing}}”
> “{{person}} ate {{thing}}”
>> r = /{{(.*?)}}/
> {{}}
>> s.match®.captures
> [“person”]
Using String#scan pulls out all tokens you were searching for:
>> s.scan®.flatten
> [“person”, “thing”]

For those who is looking for lost country_select
country_select lives on as a plugin that can be acquired from here: http://github.com/rails/country_select/tree/master