Notes posted by tadman
RSS feed
What artemave said.
I’d remove my original note if I could, but I can’t see a way how.

Also behaves like File#expand_path
You can also use URI.join to resolve relative and absolute links:
URI.join('http://example.com/', '/example').to_s # => "http://example.com/example" URI.join('http://example.com/example', 'test').to_s # => "http://example.com/test" URI.join('http://example.com/example/', 'test').to_s # => "http://example.com/example/test" URI.join('http://example.com/example/foo', '../css').to_s # => "http://example.com/css"

See also: ActiveRecord::Base#increment
This is a class-level method. For the instance-level equivalent see: ActiveRecord::Base#increment
item = Item.find(1) item.foo_count # => 0 Item.increment_counter(:foo_count, 1) item.foo_count # => 0 item.reload item.foo_count # => 1 item.increment(:foo_count) item.foo_count # => 2

Returns a copy of the attribute contents
As szeryf notes, this is a really expensive method, but another important remark is that the contents returned are a copy of the actual values.
model.attributes['name'] # => 'Joe' model.attributes['name'] = 'Jim' model.attributes['name'] # => 'Joe' still model.name # => 'Joe'
This has the potential to be confusing as you’re given the impression you have direct access to the attributes.

ActiveRecord::RecordNotSaved can be triggered by accidental false return values in callbacks
You may have this exception raised if any of the defined callbacks such as ActiveRecord::Base#before_save or ActiveRecord::Base#before_create return false.
This can happen accidentally. For example:
class MyModel < ActiveRecord::Base before_save :assign_default_foo protected def assign_default_foo self.foo = false end end
Since assign_default_foo leaves a false value on the stack, the model will not be saved. A way around this is to simply leave nil or an empty return instead:
class MyModel < ActiveRecord::Base before_save :assign_default_foo protected def assign_default_foo self.foo = false nil end end

Symbol Keys Only
While OpenStruct#new is rather indifferent to the kind of keys submitted, marshal_load requires Symbol keys only. Use of a string can cause difficulty.
To fix:
marshal_load(hash.inject({ }) { |h, (k,v)| h[k.to_sym] = v; h })
As a note, Rails has the Hash#symbolize_keys method that can be used in place.

Method functions like Hash#merge!
This method functions a lot like Hash#merge! only with a different name.
f = OpenStruct.new # => #<OpenStruct> f.marshal_load({:foo => 'bar'}) # => #<OpenStruct foo="bar"> f.foo # => "bar"

Like JavaScript Object
For those familiar with JavaScript naked Objects, this is very similar.

Equivalent to Array#reject!
This method is functionally identical to Array#reject!


Moved to ActiveSupport::Inflector
This isn’t gone, it’s just been moved to the ActiveSupport module namespace.

Tip: Define from_param(...) as Opposite
Often when defining a to_param method, it’s handy to introduce an opposite method for decoding them. For example:
class User < ActiveRecord::Base def self.from_param(param) find_by_name!(param) end def to_param name end end
While you can just as easily redefine the find() method, this may be confusing since the expectation is that find() works with numerical IDs, or whatever the key column is defined as.

Find symlink target path
To find the target of a symlink, use File.readlink

For the filename use File.basename
File.basename provides what File.dirname omits.

Argument Ordering
Be aware that the order of arguments for this method is the opposite of File.join:
File.expand_path('foo', '/bar') # => "/bar/foo" File.join('foo', '/bar') # => "foo/bar"

See Also: IO Class Methods
There are other more specific methods defined in the IO class: IO.open for files, IO.popen for pipes.

Customize Formatting with a Subclass
Instead of passing in a formatter block, you can always create a subclass that defines the format:
require 'logger' class MyLogger < Logger def format_message(severity, datetime, progname, msg) "[%s %s] %s\n" % [ severity, datetime.strtftime("%H:%M"), msg ] end end
This can be easier than always passing the same formatter option.

Rails and Ruby 1.8.7 Extensions
Note that the use of Symbol#to_proc requires either Rails or Ruby 1.8.7. Prior versions will show:
['a', 'b', 'c'].collect(&:capitalize) # => TypeError: wrong argument type Symbol (expected Proc)

To throw an exception, use Kernel#raise
Other languages use the term throw for raising exceptions, but Ruby has a specific raise call for that.

Extracting the First Element
To extract the first element from an Array, use shift:
array = [ 1, 2, 3 ] # => [ 1, 2, 3 ] array.first # => 1 array # => [ 1, 2, 3 ] array.shift # => 1 array # => [ 2, 3 ]

Extracting the Last Element
To remove the last element from the Array, use pop:
array = [ 1, 2, 3 ] # => [ 1, 2, 3 ] array.last # => 3 array # => [ 1, 2, 3 ] array.pop # => 3 array # => [ 1, 2 ]

Parameters for Hash#inject
When running inject on a Hash, the hash is first converted to an array before being passed through.
The typical Enumerable#inject approach would be to simply capture the value:
array.inject(...) do |c, v| end
In the case of a Hash, v is actually a key/value pair Array. That is the key is v.first and the value is v.last, however using the pair this way is awkward and can lead to confusion.
Better to simply expand the parameters in the block definition:
hash.inject(...) do |c, (k, v)| end
Where c is the traditional carry variable and k/v represent key and value respectively.

Deprecation warning for old-style options
You will get a warning if you don’t define your separators as a hash:
DEPRECATION WARNING: number_with_delimiter takes an option hash instead of separate delimiter and precision arguments
So while you can still use that style, it’s not without a scolding.

Define handlers in order of most generic to most specific
The later the definition of the rescue handler, the higher the priority:
rescue_from Exception, :with => :error_generic rescue_from Exception::ComputerOnFire, :with => :panic
Declaring the Exception catch-all handler last would have the side-effect of precluding any other handlers from running.
This is what is meant by being “searched…from bottom to top”.

Method has moved to ActionController::Rescue::ClassMethods module
This method has simply moved, still works the same way in 2.3+
New location: ActiveSupport::Rescuable::ClassMethods#rescue_from

Like select_values for multiple values
The names are somewhat confused:
Model.connection.select_values("SELECT id,name FROM users") => ["1","2","3"] Model.connection.select_rows("SELECT id,name FROM users") => [["1","amy"],["2","bob"],["3","cam"]]

select_values returns Strings for MySQL
This method will return all values as strings from MySQL. It is easy to convert if required, for example, to integers:
select_values("SELECT id FROM companies LIMIT 3") => ['1','2','3'] select_values("SELECT id FROM companies LIMIT 3").collect(&:to_i) => [1,2,3]

Returns the element, not block result
Enumerable#find will always return the element that is found, not the result of the block provided.

Sorting Hashes with Symbol Keys
To sort a hash with symbol keys, use Enumerable#sort_by:
h = { :a => 20, :b => 30, :c => 10 } h.sort # => NoMethodError: undefined method `<=>' for :a:Symbol h.sort_by { |k,v| k.to_s } # => [[:a, 20], [:b, 30], [:c, 10]]