Flowdock

Recent notes

RSS feed
April 12, 2009
1 thank

To find a tag with an id or class

assert_select ‘td.highlight’, { :count => 2 }

finds 2 td tags with the highlight class.

assert_select ‘div#special’

finds div with id=special

April 12, 2009
0 thanks

Takes attribute as a symbol

Attribute must be passed as a symbol:

User.toggle(:funny)

not

User.toggle(funny)
April 9, 2009
0 thanks

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.

April 9, 2009
1 thank

Outside of app code

How do I call this from script/console?

April 9, 2009
11 thanks

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”.

April 9, 2009
4 thanks

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

April 9, 2009
1 thank

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"]]
April 9, 2009
1 thank

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]
April 8, 2009
2 thanks

use create table :force => true

if you want to drop a table before creating one in a migration, use the :force => true option of the create_table method

April 8, 2009 - (>= v2.3.2)
13 thanks

Setting child_index while using nested attributes mass assignment

When using nested attributes mass assignment sometimes you will want to add new records with javascript. You can do it with pure javascript, but if HTML is long your javascript will be long and messy and it will not be DRY as probably you already have a partial for it.

So to add a partial dynamically you can do something like that (notice string “index_to_replace_with_js”):

link_to_function

def add_object_link(name, form, object, partial, where)
  options = {:parent => true}.merge(options)
  html = render(:partial => partial, :locals => { :form => form}, :object => object)
  link_to_function name, %{
    var new_object_id = new Date().getTime() ;
    var html = jQuery(#{js html}.replace(/index_to_replace_with_js/g, new_object_id)).hide();
    html.appendTo(jQuery("#{where}")).slideDown('slow');
  }
end

js method in one of helpers (from minus mor plugin)

def js(data)
  if data.respond_to? :to_json
    data.to_json
  else
    data.inspect.to_json
  end
end

This method will generate link adding generated partial to html.

The thing that is not mentioned in docs is how to set child_index. You must add it as an argument in hash.

Example of partial

<% form.fields_for :tasks, task, :child_index => 
       (task.new_record? ? "index_to_replace_with_js" : nil) do |tasks_form| %>
  <% tasks_form.text_field :name %>
<% end %>

Using add_object_link

<% form_for :project do |form| %>
  <div id="tasks">
    <%# displaying existing tasks %>
  </div>

  <%= add_object_link("New task, form, Task.new, "task", "#tasks") %>

<% end %>

Thanks to child_index after insertion it will change indexes to current time in miliseconds so added tasks will have different names and ids.

April 8, 2009 - (>= v2.2.1)
1 thank

Translations of label method

The label method won’t use your translated attribute names - which seems like big disadvantage of this method.

For a quick workaround, try using this in a helper:

def label(object_name, method, text = nil, options = {})
  text ||= object_name.classify.constantize.human_attribute_name(method.to_s)
  ActionView::Helpers::InstanceTag.new(object_name, method, self, 
    options.delete(:object)).to_label_tag(text, options)
end

I didn’t properly test this, but it seems to work.

April 8, 2009 - (v2.3.2)
6 thanks

Superclass of OrderedHash

Note that in Rails 2.3, OrderedHash changed from being a subclass of Array to a subclass of Hash. This is contrary to what the documentation says above.

April 6, 2009
5 thanks

HTML entities in options

Unfortunately everything is escaped with ERB::Util#html_escape. Your only option is either manually construct options or compeletely overwrite this method.

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