Flowdock

Recent notes

RSS feed
April 6, 2009
6 thanks

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]}
April 6, 2009
3 thanks

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$/
April 6, 2009
3 thanks

Assets hosts

You can also setup assets hosts in enviroments:

config.action_controller.asset_host = "http://your-assets-server.com"
April 3, 2009
12 thanks

The docs are in AR::Base

The docs you’re looking for are in ActiveRecord::Base

April 2, 2009
1 thank

Patch looks good.

I assume commenting right below the ticket is the “+1” action? :) Thanks for the reply and patch efforts!

April 2, 2009
2 thanks

Exension module patch

I’d say its just an oversight.

If you’d like to see all associations get equal support for extension modules take a look at this patch and give it a +1.

April 2, 2009
0 thanks

Why such inconsistency on 'extend' design?

Thanks for the great note! Finally… it took me quite some time to find this page and track down why there is such inconsistency between belongs_to and, say, has_many, proxy extension design. Do you (or anyone knowledgeable here) know the reason behind such design inconsistency? It’s quite annoying (and quite abstraction- and documentation-defeating) that one has to look this deep into the source code to see what’s going on.… Thanks!

April 1, 2009
1 thank

Returns the element, not block result

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

April 1, 2009
5 thanks

Ordering of format blocks is important

The order in which your format blocks appear, like:

format.html { } format.js { }

are used to infer priority in cases where the appropriate format is ambiguous.

April 1, 2009
0 thanks

Conflicts with 1.8.7 (and 1.9.1)

“abc”.to(0) fails in 1.8.7 and “String” should be “String” (or “abc”). Using to_a breaks in 1.9.1.

I’m using “abc”. :(

April 1, 2009 - (>= v2.1.0)
2 thanks
March 31, 2009 - (>= v2.3.2)
1 thank

Reconfiguring the Rails cleaner

The Rails cleaner is available from the top-level Rails class:

Rails.backtrace_cleaner
March 31, 2009
3 thanks

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]]
March 31, 2009 - (v2.0.0 - v2.3.2)
3 thanks

Override fieldWithErrors markup in Rails > v2

The code posted by @hosiawak will still work in recent versions of Rails, but maybe a more current, idiomatic way to do it is to stick this inside the Rails::Initializer block in environment.rb (obviously you’ll also need to restart your server to pick up the config change):

config.action_view.field_error_proc = Proc.new {|html_tag, instance| 
  %(<span class="fieldWithErrors">#{html_tag}</span>)}
March 31, 2009
0 thanks

Input for trigonometric functions must be radians

You must use radians to have the right result. For example to compute the sin of 125 degrees use:

Math.sin(125*Math::PI/180)

March 27, 2009
4 thanks

Hour with/without preceding zero

One gotcha is the difference between the hour in 12 hour time with and without a preceding zero. In some fonts they look the same.

With preceding zero (capital I)

Time.now.strftime("%I:%M") # => 05:21

Without preceding zero (lowercase L)

Time.now.strftime("%l:%M") # => 5:21
March 27, 2009
0 thanks

Hour with/without preceding zero

One gotcha is the difference between the hour in 12 hour time with and without a preceding zero. In some fonts they look the same.

With preceding zero (capital I)

Time.now.strftime("%I:%M") # => 05:21

Without preceding zero (lowercase L)

Time.now.strftime("%l:%M") # => 5:21
March 27, 2009
3 thanks

Usage

Here’s how to use it, just so it’s perfectly clear:

skip_before_filter :method_to_skip, :only => [:method_name]
March 27, 2009
1 thank

Deprecated - replacement method

The description rightly lists this as deprecated, but using it will still work atm, as it seems to have moved to ActiveSupport::CoreExtensions::Module instead.

So your code should still work.

March 27, 2009
3 thanks

multiple filter example

actually you can have it even shorter with:

before_filter :authorize, :set_locale, :except => :login
March 27, 2009 - (>= v2.1.0)
1 thank

Gotcha with method calls inside select loop

Keep in mind that any methods you call on the object in the select loop will be strung together when the Javascript is rendered. For example:

page.select(".shipping_type_fee").each do |td|
  td.down("span").update("--").show
  td.down("img").hide
end

will be rendered as:

$$('.shipping_type_fee').each(function(value, index) {
  value.down("span").update("--").show().down("img").hide();
});

This is probably not what you want!

March 26, 2009
0 thanks
March 26, 2009 - (v2.0.0 - v2.3.2)
1 thank
March 25, 2009 - (>= v2.2.1)
1 thank

usage helper with block

helper example

def my_helper(&block)
  inner = capture(&block)
  out = "<somehtml>#{inner}</somehtml>"
  block_called_from_erb?(block) ? concat(out) : out
end

view example

<% my_helper do %>
  sometext
<% end %>

output

<somehtml>sometext</somehtml>

using ActionView::Helpers::CaptureHelper#capture

March 25, 2009 - (>= v2.2.1)
1 thank

alternative

not sure but block_called_from_erb? seems to be the replacement

March 24, 2009 - (>= v2.3.2)
2 thanks

if you get NameError: uninitialized constant ActionController::Caching::Sweeper

I got hit with this on an upgrade. Had a reference to ApplicationController::Base in development.rb (prod as well) which caused this problem http://rails.lighthouseapp.com/projects/8994/tickets/1977

Fix was to remove the loading of ApplicationController::Base and put it in an initializer (where it should have been).

March 24, 2009
1 thank

Content_tag in helpers

Content_tag works great in a helper and is a nice way to clean up your views.

If you’re returning more than one content_tag you’ll need to concat them:

@content = content_tag(:tr, "first item")
@content << content_tag(:tr, "second item")

Be mindful that when doing the above, you must use parentheses around the content_tag options. In the above example, content_tag :tr, “second item” will return an error.

March 24, 2009
0 thanks

Finding all records WITHOUT associations

(Thanks to someone on the rails IRC channel who gave me this tip.)

Where Users and Events have a habtm relationship, to find all Users that have no events:

User.find(:all, :include => :events, :conditions => { "events_users.event_id" => nil})

(Note that when specifying a condition on a joined table, you have to put the field name in a string rather than a symbol. In the above example, :events_users.event_id will not work.)

March 24, 2009
1 thank

New and improved version

As this method is now deprecated, check the documentation for the new version (adds some more options), which gets included via a module:

ActiveRecord::Serialization#to_xml