Notes posted by insane-dreamer

RSS feed
August 2, 2010
0 thanks

assert_select negative with regex

(also, you can use instance vars)

assert_select "div#event_#{assigns[event].id}", { :count => 0, :html => /something/ }
July 23, 2010
2 thanks

To use in testing

If you want to use this in a test, add the following to test_helper.rb:

include ActionDispatch::TestProcess

(If using factory_girl, you can call it in your Factory, like so:

f.photo { fixture_file_upload 'test.png', 'image/png' }
July 23, 2010
3 thanks

Moved in Rails 3

In Rails 3, this has moved to ActionDispatch::TestProcess

(Which means, if you want to use it in a test, you need to add the following to test_helper.rb:)

include ActionDispatch::TestProcess
December 2, 2009
2 thanks

IE GOTCHA - multiple javascript_include_tags with cache => true

If you have multiple lines of javascript_include_tag ‘jsfile’, :cache => true, IE does not load them all (though it seems Firefox and Safari do). And the error won’t show up until you’re in production (since that’s only when caching kicks in.)

You should include them all on one line:

javascript_include_tag 'file1.js', 'file2.js', 'file3.js', :cache => 'myfiles'
November 30, 2009
0 thanks

You can specify the format as well

You can also specify the format (in case you need to redirect a request coming in one format to another format):

redirect_to :action => 'show', :format => 'html'
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)
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 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 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 12, 2009 - (<= v2.1.0)
0 thanks

Another fix

Another way around this problem, with code that already employs String.first, is to change the ActiveSupport definition as follows (in environment.rb)

module ActiveSupport
  module CoreExtensions 
    module String 
      module Access
        def first(limit = 1)
          chars.to_a[0..(limit - 1)].to_s
        end
      end
    end
  end
end
March 12, 2009
2 thanks

Incompatible with Ruby 1.8.7

If using Rails < 2.2 with Ruby 1.8.7, calling truncate will result in the following error:

undefined method `length' for #<Enumerable::Enumerator:0xb74f952c>

The workaround (other than upgrading to Rails 2.2 or higher), is to overwrite the truncate method, by inserting the following at the end of environment.rb (or where it will be called on startup):

module ActionView
  module Helpers
    module TextHelper
      def truncate(text, length = 30, truncate_string = "...")
        if text.nil? then return end
        l = length - truncate_string.chars.to_a.size
        (text.chars.to_a.size > length ? text.chars.to_a[0...l].join + truncate_string : text).to_s
      end
    end
  end
end
March 12, 2009
0 thanks

PS

That didn’t render properly. Use:

String[1..1]

instead of

String.first
February 26, 2009 - (v1.0.0 - v2.1.0)
0 thanks

Conflicts with Ruby 1.8.7

Using this with Rails < 2.2.x and Ruby 1.8.7 will create a conflict between ActiveSupport and Ruby, generating the following error:

>> '/'.first
NoMethodError: undefined method `[]' for #<Enumerable::Enumerator:0x176b974>
  from /opt/local/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/core_ext/string/access.rb:43:in `first'

So if using an older version of Rails with Ruby 1.8.7, use String to instead of String.first