Flowdock

Recent notes

RSS feed
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
4 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
2 thanks

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

March 23, 2009 - (v2.3.2)
4 thanks

So, how do you enable db sessions?

First, run:

rake db:sessions:create

Then, run your pending migrations. This will create the migration you need to run in order to create the sessions table.

Second, go into config/environment.rb and uncomment or put in:

config.action_controller.session_store = :active_record_store
config.action_controller.session = {
   :session_key => '_your_session_name_here',
   :secret      => 'SOME_CRYPTOGRAPHICALLY_SECURE_KEY'
 }

Third, get yourself a secure key with:

rake secret

And finally, paste your new key into the :secret above.

March 21, 2009
1 thank

Generating empty conditions

In some cases, you might find it useful for your lamba to generate empty conditions based on the passed parameter.

Class Article << ActiveRecord::Base

named_scope :category, lambda { |cat|
  if cat == :all
    { :conditions => {} }
  else
    { :conditions => { :category_id => cat } }
  end  
}

end

Allows you to call something like this:

categories = user_is_admin ? :all : @current_category
Article.category(categories)

Mostly useful when chaining named_scopes together. Avoids more complicated if statements.

March 21, 2009
4 thanks

Passing optional arguments with defaults to a named_scope

An easy way to do this. (This also shows how you can use joins in a named_scope as well.)

Class User << ActiveRecord::Base
belongs_to :semester 

named_scope :year, lambda { |*year|
  if year.empty? || year.first.nil?
    { :joins => :semester, :conditions => ["year = #{CURRENT_SEMESTER}"]}
  else
    { :joins => :semester, :conditions => ["year = #{year}"]}
  end
  }

end

You can then call:

User.year     # defaults to CURRENT_SEMESTER constant
User.year()  # same as above
User.year(nil)  # same as above; useful if passing a param value that may or may not exist, ie, param[:year]
User.year(2010)
March 21, 2009
0 thanks

Remember, named_scope returns an array

named_scope always returns a named_scope object, that acts like an array, even if you’re using it to only find one record. So if you’re trying to perform an association on the results of a named_scope, use the first method to return the model object and not the named_scope object.

Ie:

user = User.my_name_scope
user.articles   # assuming User has_many Articles

will return an error. use this instead:

user = User.my_named_scope.first
user.articles

(Of course this is a poor example because what you should be doing is performing the named_scope on Article with user as the condition, instead of on User. But if you do need to use the results of a named_scope to perform an association call, you have to do it this way to avoid an error.)

March 21, 2009
7 thanks

Use helpers in your ActionMailer views

It’s very easy to give your mailer access to helpers:

# Let your mailer user the ApplicationHelper methods
class MyMailer < ActionMailer::Base
  helper :application
end
March 20, 2009 - (>= v2.0.0)
9 thanks

Use the current URL, with changes

You can use the current URL, whatever it is, with changes, as in:

# Create a link to the current page in RSS form
url_for(:overwrite_params => {:format => :rss})

This can be super-helpful because it preserves any GET params (like search parameters)

March 20, 2009
2 thanks

Broadened Flash helper

Building on the below excellent example, you can create something with default options for how long it’s displayed and how long the fade is, and highlight:

def show_flash(options={})
  options = {:fade => 3, :display => 3, :highlight => true}.merge(options)
  html = content_tag(:div, flash.collect{ |key,msg| content_tag(:div, msg, :class => key, :attributes => "style = display: none;") }, :id => 'flash-message')
  html << content_tag(:script, "new Effect.Highlight('flash-message');") if options[:highlight]
  html << content_tag(:script, "$('flash-message').appear();")
  html << content_tag(:script, "setTimeout(\"$('flash-message').fade({duration: #{options[:fade]}});\", #{options[:display]*1000});")
end
March 20, 2009 - (v2.2.1)
0 thanks
March 20, 2009 - (>= v2.3.2)
1 thank
March 20, 2009 - (>= v2.3.2)
0 thanks

Nested Model Forms

For a good example of nested model forms check out the rails blog.

http://weblog.rubyonrails.org/2009/1/26/nested-model-forms