Flowdock

Recent notes

RSS feed
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)
2 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' } 
May 15, 2009
0 thanks

script/generate can take table name

As far as I can tell script/generate will happily take the plural table name, at least in Rails 2.3.

May 13, 2009
3 thanks

Equivalent to Array#reject!

This method is functionally identical to Array#reject!

May 12, 2009
2 thanks

form_authenticity_token

Instead of disabling the CSRF check you can pass the authenticity_token field in your forms, eg:

<%= hidden_field_tag :authenticity_token, form_authenticity_token -%>
May 8, 2009
2 thanks

Using gmail SMTP server to send mail

If you’re running Rails >= 2.2.1 [RC2] and Ruby 1.8.7, you don’t need plugin below. Ruby 1.8.7 supports SMTP TLS and Rails 2.2.1 ships with an option to enable it if you’re running Ruby 1.8.7.

All You need to do is:

ActionMailer::Base.smtp_settings = {
  :enable_starttls_auto => true
}
May 7, 2009
0 thanks

RESTful actions

REST adds many constraints. It restricts your controllers to seven actions. Normally this is okay, but sometimes you need to add your own custom actions.

http://railscasts.com/episodes/35-custom-rest-actions

May 7, 2009 - (v2.2.1 - v2.3.2)
1 thank

Question

Can someone add some more information to this?

May 7, 2009
0 thanks

question?

Shouldn’t the second example be:

[1,2].zip(a,b)         #=> [[1, 4, 7], [2, 5, 8], [nil,6,9]]

??? or am I missing something?

May 7, 2009 - (v1_8_6_287 - v1_8_7_72)
0 thanks

Reg Ex Syntax

Is there any place where there is a full listing of RegEx syntax?

May 6, 2009 - (>= v2.3.2)
1 thank

Formatted route helpers are gone

In Rails >= 2.3 you can’t use formatted_xxx url helpers anymore.

However, you can still pass a :format option to url helpers, eg:

articles_path(:format => :csv) # => /articles.csv
May 4, 2009 - (v1_8_6_287)
2 thanks

NoMethodError: undefined method `each_char'

For some reason the each_char method on String is not available by default in Ruby 1.8.6 and you will be presented with a NoMethodError.

You can resolve this by requiring the jcode lib:

require 'jcode'
May 4, 2009
1 thank

clarification

Via Kenneth Kalmer:

From the man page: If salt is a character string starting with the characters “$id$” followed by a string terminated by “$”: $id$salt$encrypted then instead of using the DES machine, id identifies the encryption method used and this then determines how the rest of the password string is interpreted.

irb session

=>abNANd1rDfiNc”
irb(main):002:0>secret”.crypt(”abasasa”)
=>abNANd1rDfiNc”
irb(main):003:0>secret”.crypt(”$1$abasasa”)
=>$1$abasasa$2RZY2vd6E2ZEPSDa0eLec0″
irb(main):004:0>secret”.crypt(”$1$abasa”)
=>$1$abasa$ikoKICgwOFdcWgmDl9Asy1″

see http://www.opensourcery.co.za/2009/05/01/quick-nix-shadow-passwords-with-ruby/

May 2, 2009 - (v2.0.0 - v2.3.2)
0 thanks

Setting name and id for select_tag

Sometimes you need to use select_tag instead of select (because you’re after more control or need to use optgroups, for example), but still want the id/name conventions that select would give.

In this case, all you need to do is set the first parameter to whatever would be produced by select, and it’ll take care of the id and name attribute automatically, and thus ensure the form data is parsed correctly after submission.

For example, if you want to do something like:

form_for :comment do |f|
 f.select :article_id ...

which would give a select tag with id of “comment_article_id” and a name attribute of “comment[article_id]”, which be parsed into the params hash of:

'comment' => {'article_id' => ...

you can instead do

form_for :comment do |f|
 select_tag 'comment[article_id]' ...

which will give the same id and name attributes for the select tag and hence the same params hash in the controller

May 2, 2009
0 thanks

Re: Find random record

How about if you wanted to find a random set of records instead of a singular record, what would be the best way?

Thank you

May 2, 2009
8 thanks

Create a Hash from two Arrays

Here is my favorite idiom for creating a Hash from an Array of keys and an Array of values:

keys = [:a, :b]
values = [1,2]
h = Hash[*keys.zip(values).flatten]      # => {:b=>2, :a=>1}
May 2, 2009
3 thanks

Test if one array includes the elements of another

You can just use a set difference (aka minus) to see if one array includes all elements of another

not_included = [1,2,3] - (1..9).to_a
not_included      # => []

not_included = [1,2,3,'A'] - (1..9).to_a
not_included      # => ["A"]

Use intersection to test if any of the one are in the other:

shared = [1,2,3,'A'] & (1..9).to_a
shared     # => [1, 2, 3]