Flowdock

Recent notes

RSS feed
February 16, 2009
1 thank

See max

See max for comments and more usage examples.

February 16, 2009
2 thanks

Capping values

This method is very useful when you want to cap values:

# minimum ≤ value 
value = [input.to_i, minimum].max

# value ≤ maximum
value = [input.to_i, maximum].min

# minimum ≤ value ≤ maximum
value = [ [input.to_i, minimum].max, maximum ].min

# Practical example: Make sure destination is within container
destination.x = [ [current.x + current.velocity.x, 0].max, container.width  ].min
destination.y = [ [current.y + current.velocity.y, 0].max, container.height ].min
February 16, 2009
5 thanks

Usage example

Some examples:

# Remove even numbers
(1..30).reject { |n| n % 2 == 0 }
# => [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29]

# Remove years dividable with 4 (this is *not* the full leap years rule)
(1950..2000).reject { |y| y % 4 != 0 }
# => [1952, 1956, 1960, 1964, 1968, 1972, 1976, 1980, 1984, 1988, 1992, 1996, 2000]

# Remove users with karma below arithmetic mean
total = users.inject(0) { |total, user| total += user.karma }
mean = total / users.size
good_users = users.reject { |u| u.karma < mean }
February 16, 2009
1 thank

Reverse of this

If you want to do the reverse of this, e.g. go from a specific date and back to a certain day of the previous week, you can implement it like this:

def last_week(day = :monday)
  days_into_week = { :monday => 0, :tuesday => 1, :wednesday => 2, :thursday => 3, :friday => 4, :saturday => 5, :sunday => 6}
  result = (self - 7).beginning_of_week + days_into_week[day]
  self.acts_like?(:time) ? result.change(:hour => 0) : result
end

If you do not want to make your own method of this, but just want to do it in a regular chaining of date methods (like Date.today.next_year.at_midnight), you can do it like the following:

(date - 7).next_week(:tuesday) # Tuesday, last week

Please note that you just need to subtract 7 if you want to move back a week. Only use these methods if you want to go to a specific day of the week.

February 16, 2009
1 thank

Reverse naming

The reverse of this is last_month and not previous_month, like one might believe from the naming.

February 16, 2009
1 thank

Reverse naming

The reverse of this is last_year and not previous_year, like one might believe from the naming.

February 15, 2009
0 thanks

use #collect instead of #each

The earlier reminder to use #collect instead of #each applies regardless of whether the tag is nested or not.

This is counterintuitive, as #collect returns an array of strings of HTML tags, but ActionView renders it properly.

February 14, 2009
1 thank

Clear and simple rescue

noxyu3m, your code is rescuing all exceptions, not just ActiveRecord::RecordInvalid.

I think this syntax is a bit more clear than using the global variable.

def create
  @model = Model.new(params[:model)
  @model.save!
rescue => err                          # rescues all exceptions
  logger.error(err.to_s)
end
February 14, 2009
0 thanks

Simple rescue

Take it easy:

def create
  @model = Model.new(params[:model)
  @model.save!
rescue
  logger.error(!$.to_s)
end

Global variable !$ refers to the Exception object.

February 13, 2009
1 thank

throws exception

when use use Model.find([1,2,3,4])

throws exception if no record exists with any of this ID

February 13, 2009
3 thanks

New test syntax

You can use either one and even mix in the same test case if you want:

class Test < Test::Unit::TestCase
  # old way to define a test method (prefix with test_)
  def test_should_be_valid_without_content
    assert Comment.new.valid?
  end

  # new way to define a test
  test "should be valid without content" do
    assert Comment.new.valid?
  end
end
February 12, 2009
4 thanks

Real life use

If you’re wondering what the base64 format is used for, here are some examples:

  • HTTP Basic authentication: encode your username and password as one string, and add it as a header of an HTTP request. When a page requiring basic authentication gets called from a browser it results in a generic Username/Password dialog from that browser. See also http://en.wikipedia.org/wiki/Basic_access_authentication

  • Encode the binary content of images to base64 and embed it in XML documents, for example in web services

  • For more information see http://en.wikipedia.org/wiki/Base64

Just note that the encoded (character) data is about 30% larger than un-encoded (binary) data.

February 12, 2009
0 thanks

using collection=objects

It will fire one insert query per new record

February 12, 2009
4 thanks

Binary files

Another real important flag is b when dealing with binary files. For example to download an mp3 from the internet you need to pass the b flag or the data will be screwed up:

# Downloads a binary file from the internet
require 'open-uri'
url = "http://fubar/song.mp3"
open(url, 'rb') do |mp3|
  File.open("local.mp3", 'wb') do |file|
    file.write(mp3.read)
  end
end

Don’t say you haven’t been warned. :)

February 12, 2009
3 thanks

Other regular-expression modifiers

Likewise you can set Regexp::IGNORECASE directly on the regexp with the literal syntax:

/first/i
# This will match "first", "First" and even "fiRSt"

Even more modifiers

  • o – Perform #{} interpolations only once, the first time the regexp literal is evaluated.

  • x – Ignores whitespace and allows comments in * regular expressions

  • u, e, s, n – Interpret the regexp as Unicode (UTF-8), EUC, SJIS, or ASCII. If none of these modifiers is specified, the regular expression is assumed to use the source encoding.

Literal to the rescue

Like string literals delimited with %Q, Ruby allows you to begin your regular expressions with %r followed by a delimiter of your choice.

This is useful when the pattern you are describing contains a lot of forward slash characters that you don’t want to escape:

%Q(http://)
# This will match "http://"
February 12, 2009
4 thanks

Literal syntax

As you propably know you can create an Array either with the constructor or the literal syntax:

Array.new == []
# => true

But there is also another nice and concise literal syntax for creating Arrays of Strings:

["one", "two", "three"] == %w[one two three]
# => true

You can use any kind of parenthesis you like after the %w, either (), [] or {}. I prefer the square brackets because it looks more like an array.

February 12, 2009
2 thanks

Use this!

You should raise your own ArgumentError in methods to notify users of your class, if you think certain kinds of arguments aren’t acceptable.

def transfer_money(amount)
  unless amount.is_a?(Number)
    raise ArgumentError.new("Only numbers are allowed")
  end
  # ... Do the actual work
end
February 12, 2009
3 thanks

Useful scenario

This can be quite useful, for example when writing a command line script which takes a number of options.

Example

Let’s say you want to make a script that can make the basic CRUD operations. So want to be able to call it like this from the command line:

> my_script create
> my_script delete

The following script allows you to use any abbreviated command as long as it is unambiguous.

# my_script.rb
require 'abbrev'

command = ARGV.first
actions = %w[create read update delete]
mappings = Abbrev::abbrev(actions)
puts mappings[command]

That means you can call it like this:

> my_script cr
> my_script d

And it will print:

create
delete
February 10, 2009
8 thanks

Security issue with non-HTML formats

Please note that using default to_xml or to_json methods can lead to security holes, as these method expose all attributes of your model by default, including salt, crypted_password, permissions, status or whatever you might have.

You might want to override these methods in your models, e.g.:

def to_xml
  super( :only => [ :login, :first_name, :last_name ] )
end

Or consider not using responds_to at all, if you only want to provide HTML.

February 10, 2009
0 thanks

Cheat Sheet

I have written a short introduction and a colorful cheat sheet for Perl Compatible Regular Expressions (PCRE) as used by Ruby’s Regexp class:

http://www.bitcetera.com/en/techblog/2008/04/01/regex-in-a-nutshell/

February 10, 2009
0 thanks

Cheat Sheet

I have written a short introduction and a colorful cheat sheet for Perl Compatible Regular Expressions (PCRE) as used by Ruby’s Regexp class:

http://www.bitcetera.com/en/techblog/2008/04/01/regex-in-a-nutshell/

February 10, 2009
3 thanks

Cheat Sheet

I have written a short introduction and a colorful cheat sheet for Perl Compatible Regular Expressions (PCRE) as used by Ruby’s Regexp class:

http://www.bitcetera.com/en/techblog/2008/04/01/regex-in-a-nutshell/

February 10, 2009
2 thanks
February 10, 2009
0 thanks

Output format

This outputs date & time in format of yyyy-MM-ddThh-mm-ssZZZ. All values are preceded with 0 if less than 10. Hours are in 0..23 range. Timezone is sticked at the end. Watch out for capital T in the middle :)

February 9, 2009
5 thanks
February 9, 2009
1 thank

:foreign_type option

I’m not sure if this has always been around but in 2.3, belongs_to takes a :foreign_type option on polymorphic associations. This behaves the same way as :foreign_key but for the type field.

February 9, 2009
2 thanks

Calculating on an enumerable

Inject can easily be used to sum an enumerable or to get the product of it

[100, 200, 1000].inject(0) { |sum, value| sum += value } # => 1300
[100, 200, 1000].inject(1) { |sum, value| sum *= value } # => 20000000

# You can access members and move down in the data structures, too
points.inject(0) { |sum, point| sum += point.y }

In the case of the first two examples, an easier way to do it in Ruby 1.9 is to use reduce:

[100, 200, 1000].reduce :+ # => 1300
[100, 200, 1000].reduce :* # => 20000000

Look at reduce for more examples on how to use this.

February 8, 2009
0 thanks

Can be used on classes, too

For example:

class C
  protected
    def foo
    end 
end
p C.protected_instance_methods(false)

outputs:

["foo"]
February 7, 2009 - (>= v2.2.1)
1 thank

Documentation

Good docs can be found here: http://www.artweb-design.de/2008/7/18/the-ruby-on-rails-i18n-core-api

See also: http://rails-i18n.org/wiki for an extensive list of resources.

February 7, 2009 - (>= v2.2.1)
3 thanks

Deprecated

This method is deprecated. You should use:

I18n.translate('activerecord.errors.messages')