Flowdock

Recent notes

RSS feed
June 11, 2009
2 thanks
June 10, 2009
2 thanks

[:a, :b, :c].try([1]) ? The answer is No.

Correct way is this:

[:a, :b, :c].try(:at, 1)
June 10, 2009
0 thanks

list of predefined variables

$! The exception information message set by ‘raise’. $@ Array of backtrace of the last exception thrown.

$& The string matched by the last successful pattern match in this scope. $` The string to the left of the last successful match. $‘ The string to the right of the last successful match. $+ The last bracket matched by the last successful match. $1 to $9 The Nth group of the last successful regexp match. $~ The information about the last match in the current scope.

$= The flag for case insensitive, nil by default. $/ The input record separator, newline by default. $\ The output record separator for the print and IO#write. Default is nil. $, The output field separator for the print and Array#join. $; The default separator for String#split.

$. The current input line number of the last file that was read. $< The virtual concatenation file of the files given on command line. $> The default output for print, printf. $stdout by default. $_ The last input line of string by gets or readline.

$0 Contains the name of the script being executed. May be assignable. $* Command line arguments given for the script sans args. $$ The process number of the Ruby running this script. $? The status of the last executed child process. $: Load path for scripts and binary modules by load or require.

$“ The array contains the module names loaded by require. $DEBUG The status of the -d switch. $FILENAME Current input file from $<. Same as $<.filename. $LOAD_PATH The alias to the $:. $stderr The current standard error output. $stdin The current standard input. $stdout The current standard output. $VERBOSE The verbose flag, which is set by the -v switch. $-0 The alias to $/. $-a True if option -a (”autosplit“ mode) is set. Read-only variable. $-d The alias to $DEBUG. $-F The alias to $;. $-i If in-place-edit mode is set, this variable holds the extension, otherwise nil. $-I The alias to $:. $-l True if option -l is set (”line-ending processing“ is on). Read-only variable. $-p True if option -p is set (”loop“ mode is on). Read-only variable. $-v The alias to $VERBOSE. $-w True if option -w is set.

Source: http://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Variables_and_Constants#Pre-defined_Variables

June 10, 2009 - (v1.0.0 - v2.3.2)
5 thanks

Have the check_box checked by default

To have the check box checked by default, pass either :checked => true or :checked => 'checked' in the options. See ActionView::Helpers::InstanceTag#to_check_box_tag for details.

June 8, 2009 - (v2.2.1 - v2.3.2)
5 thanks

This is ON by default in :has_many

When defining a has_many relationship this behaviour is on by default. See has_many documentation, look for the :validate flag.

June 6, 2009
9 thanks

add index with :quiet=>true option for indices that are possibly already added

# Allows you to specify indices to add in a migration that will only be created if they do not # already exist, or to remove indices only if they already exist with :quiet=>true module ActiveRecord::ConnectionAdapters::SchemaStatements

def add_index_with_quiet(table_name, column_names, options = {})
  quiet = options.delete(:quiet)
  add_index_without_quiet table_name, column_names, options
rescue
  raise unless quiet and $!.message =~ /^Mysql::Error: Duplicate key name/i
  puts "Failed to create index #{table_name} #{column_names.inspect} #{options.inspect}"
end
alias_method_chain :add_index, :quiet

def remove_index_with_quiet(table_name, column_names, options = {})
  quiet = options.delete(:quiet)
  raise "no options allowed for remove_index, except quiet with this hack #{__FILE__}:#{__LINE__}" unless options.empty?
  remove_index_without_quiet table_name, column_names
rescue
  raise unless quiet and $!.message =~ /^Mysql::Error: Can't DROP/i
  puts "Failed to drop index #{table_name} #{column_names.inspect}"
end
alias_method_chain :remove_index, :quiet

end

June 4, 2009
2 thanks

A typical usage for a mock

You want to use a mock when you’re testing a behaviour of one of your methods that interacts with some outside world service (eg. an FTP server).

it "should login to ftp server" do
  ftp = mock('Ftp server', :null_object => true)
  Net::FTP.should_receive(:new).and_return(ftp)
  ftp.should_receive(:login).with('username', 'password')
  some_obj.connect
end

def connect
  session = Net::FTP.new('server.com')
  session.login('username', 'password')
  session.close
end
June 4, 2009
5 thanks

A catch-all format

If you’d like to specify a respond_to only for 1 or a few formats and render something else for all other formats, eg: (action.rss returns a feed but action.html or action.js should just render 404), use format.all:

respond_to do |format|
  format.rss { render_rss }
  format.all { render_404 }
end

Rails will render an empty string for all formats that don’t specify a response explicitly.

June 4, 2009
2 thanks

example

Ruby style

Dir[File.join(RAILS_ROOT, 'vendor', 'plugins', '*')]

Rails style

Dir[Rails.root.join('vendor', 'plugins', '*')]
June 4, 2009 - (v2.3.2)
1 thank

Security hole in 2.3.2

This method has a security hole in Rails 2.3.2. See http://weblog.rubyonrails.org/2009/6/3/security-problem-with-authenticate_with_http_digest for explanation.

Rails 2.3.3 should fix the problem.

June 3, 2009
8 thanks

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
June 3, 2009 - (<= v2.3.2)
0 thanks

multi scope to sql

validates_uniqueness_of :name, :scope => [:big_category_id, :small_category_id]

SELECT * FROM schedules WHERE (products.name = 'xxxx' AND products.big_category_id= 1 AND products.small_category_id = 1) LIMIT 1
June 2, 2009 - (v2.2.1 - v2.3.2)
1 thank

Do not create an [ ] method

I created a helper method to access some meta data using

def [](name)
  # do stuff
end

This breaks ActiveRecord behaviors. all belongs_to relations were broken

eg.

class Image
  belongs_to :album
end

i = Image.find :first
i.album_id # 1
i.album # nil

Album.find 1 # works

If you experience this behavior, you probably created a method that breaks the default systematics (like I did with the [ ] method)

June 1, 2009
1 thank

Shared examples

Use it together with share_examples_for like this:

share_examples_for "a shape" do
  it "should have a color" do
    # ...
  end

  it "should have a center point" do
    # ...
  end
end

describe "a circle" do
  it_should_behave_like "a shape"

  it "should be round" do
    # ...
  end
end
June 1, 2009 - (v2.2.1 - v2.3.2)
2 thanks

Further To: Memoize will not cache singleton methods

er…it will:

Code example

class PersonType < ActiveRecord::Base
  class << self
    # Add the mixin here:
    extend ActiveSupport::Memoizable
    def mister
      find_by_name('Mister')
    end
    memoize :mister
  end
end
June 1, 2009
0 thanks

Typical stub! usage

Typically you would call

my_object.stub!(:updated_at).and_return(time_object)
June 1, 2009
2 thanks

Make sure your action names don't step on any toes.

In my experience, if you ever have a controller action named “process”, your controller will cease to function, as there is both a class and instance method called process in ActionController::Base.

There are undoubtedly other action names that will cause conflicts, but this one is particular I’ve run into a number of times.

May 31, 2009
2 thanks

You can call several times

You can call it several times, like:

class Comment < ActiveRecord::Base
  validate :must_be_friends
  validate :must_be_awesome
  ...

or with several arguments:

class Comment < ActiveRecord::Base
  validate :must_be_friends, :must_be_awesome
  ...
May 27, 2009
0 thanks

Potentially slow operation

Remember that checking for a value is a potentially slow operation (all the elements might be iterated) as oposed to querying a key (e.g. with has_key?), which is supposed to be fast in a Hash.

May 27, 2009 - (>= v1_8_6_287)
3 thanks

map_with_index

If you want to access the element index when using map, you can do it with enum_for:

(1..6).enum_for(:each_with_index).map { |v, i| "index: #{i} value: #{v}" }
#=> ["index: 0 value: 1", "index: 1 value: 2", "index: 2 value: 3", "index: 3 value: 4", "index: 4 value: 5", "index: 5 value: 6"]
May 26, 2009
1 thank

Potentially slow operation

Remember that checking for a value is a potentially slow operation (all the elements might be iterated) as oposed to querying a key (e.g. with has_key?), which is supposed to be fast in a Hash.

May 22, 2009
0 thanks

Alternative Way to Handle

This plugin may also help solve the problem from the model side.

http://github.com/rxcfc/multi_assignment_sanity
May 22, 2009 - (v2.0.0 - v2.1.0)
1 thank

Moved

In 2.2 and greater this has moved to ActiveSupport::Dependencies::Loadable#unloadable

May 20, 2009
0 thanks

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.

May 19, 2009
0 thanks

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"
May 19, 2009
2 thanks

Like JavaScript Object

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

May 19, 2009 - (v2.2.1 - v2.3.2)
2 thanks

How to set request parameters

On previous versions of TestRequest it was possible to set the request_parameters on the new action. This option is now gone, but it’s still possible to set the parameters after initialization.

Code example

request = ActionController::TestRequest.new
request.env["action_controller.request.request_parameters"] = { :foo => '42', :bar => '24' }