Flowdock

Recent notes

RSS feed
April 22, 2011
0 thanks

Test strings with eql

Equal fails when comparing two different string objects:

"test".should equal "test" #=> fail
"test".should match "test" #=> pass
"test".should eql "test" #=> pass

In fact:

"test".object_id.should_not eql "test".object_id #=> pass

Match fails when the string contains regex special characters not escaped:

"*test*".should match "*test*" #=> fail for invalid regex
"*test*".should eql "*test*" #=> pass

In fact, match treats input as regexp:

"*test*".should match /\*test\*/ #=> pass
April 14, 2011
0 thanks

Example

Chops the last character off a string.

> a = "12345"
> a.chop
=> "1234"
> a
=> "12345"
> a.chop!
=> "1234"
> a
=> "1234
April 14, 2011
0 thanks

Why gsub!

I notice other adapters use sql.sub!, not sql.gsub! and in fact I had trouble with adding the limit parameter to any query involving nested selects. Replacing sql.gsub! with sql.sub! solved that problem for me. Has anyone else had a similar experience with this method?

In other words, replace:

sql.gsub!(/SELECT/i, 'SELECT B.* FROM (SELECT A.*, row_number() over () AS internal$rownum FROM (SELECT')

With:

sql.sub!(/SELECT/i, 'SELECT B.* FROM (SELECT A.*, row_number() over () AS internal$rownum FROM (SELECT')
April 14, 2011
0 thanks

logging before filters

If you need to track and log which before filters are called for the purpose of debugging your app/before_filters. Then here’s a suggestion, how this could be accomplished:

http://stackoverflow.com/questions/4951902/how-to-log-rails-controller-filters-during-rspec-controller-tests/5660475#5660475

April 8, 2011
0 thanks

customizing text when using label in a form

Instead of the default text Email you can change it to “Primary Email” like this: f.label :email, “Primary Email”

April 6, 2011 - (v3.0.5)
0 thanks

the source is wrong!

in 3.0.5, the source code in line 15 looks like this:

respond_to?(:"#{k}=") ? send(:"#{k}=", v) : raise(UnknownAttributeError, "unknown attribute: #{k}")

whats wrong with apidock?

April 4, 2011
2 thanks

Working with match captures

Let’s say you wanted to filter out passwords from:

s = "password=bob&password=jim&password=jane"

You’d do this:

r = /password\=([^\&]+)/
s.gsub!(r) { |m| m.gsub!($1, "[FILTERED]") }

Which would return

password=[FILTERED]&password=[FILTERED]&password=[FILTERED]
April 4, 2011 - (>= v3.0.0)
0 thanks
March 31, 2011 - (v3.0.0 - v3.0.5)
0 thanks

reload is deprecated? what's the new alternative?

What’s the recommended alternative to reload for more recent versions of Rails?

March 31, 2011
0 thanks

Test strings with match

To test a string use match, e.g.

"test".should match("test")
March 30, 2011 - (v3.0.0 - v3.0.5)
1 thank

After filters are not called when exception occurs

Please note after filters are not executed when an exception occurs. You have to handle these situations explicitly.

March 25, 2011
4 thanks

How to specify :only_path when non-hash options

When passing in an object, as opposed to a hash, you can’t do this because url_for accepts one argument:

url_for(post, :only_path => true)

Instead, do this:

polymorphic_url(object, :routing_type => :path)
March 23, 2011
0 thanks

Handling nested hashes and arrays

You can use this code to handle nested hashes and arrays. I’m not sure if it handles every case, and it could probably be refactored better, but it’s working quite well for us.

require 'active_support/core_ext/hash'

def normalize_params(params, key=nil)
  params = params.flatten_keys if params.is_a?(Hash)
  result = {}
  params.each do |k,v|
    case v
      when Hash
        result[k.to_s] = normalize_params(v)
      when Array
        v.each_with_index do |val,i|
          result["#{k.to_s}[#{i}]"] = val.to_s
        end
      else
        result[k.to_s] = v.to_s
    end
  end
  result
end

# Adapted from http://snippets.dzone.com/posts/show/6776
class Hash
  def flatten_keys(newhash={}, keys=nil)
    self.each do |k, v|
      k = k.to_s
      keys2 = keys ? keys+"[#{k}]" : k
      if v.is_a?(Hash)
        v.flatten_keys(newhash, keys2)
      else
        newhash[keys2] = v
      end
    end
    newhash
  end
end
March 23, 2011
2 thanks

Timestamps

Note that ActiveRecord will not update the timestamp fields (updated_at/updated_on) when using update_all().

March 23, 2011 - (v3.0.0 - v3.0.5)
0 thanks
March 23, 2011 - (v3.0.0 - v3.0.5)
1 thank
March 22, 2011
0 thanks

Find a random *set* of records (without killing the db)

If you want to find any number of records without sorting your entire table randomly every time, try the solution I posted here:

http://rubyglasses.blogspot.com/2010/05/activerecord-find-in-random-order.html

March 21, 2011 - (v3.0.0 - v3.0.5)
0 thanks
March 16, 2011 - (<= v2.3.8)
0 thanks
March 15, 2011
0 thanks

Don't cache it!

Don’t store a connection in a variable, because another thread might try to use it when it’s already checked back in into the connection pool. See: ActiveRecord::ConnectionAdapters::ConnectionPool

connection = ActiveRecord::Base.connection

threads = (1..100).map do
  Thread.new do
    begin
      10.times do
        connection.execute("SELECT SLEEP(1)")  # WRONG
        ActiveRecord::Base.connection.execute("SELECT SLEEP(1)")  # CORRECT
      end
      puts "success"
    rescue => e
      puts e.message
    end
  end
end

threads.each(&:join)
March 14, 2011
0 thanks

formating date

I18n.l Time.now, :format => “%e %B”

http://snippets.dzone.com/posts/show/2255

March 14, 2011
1 thank

Looking for method "l" and "t"

translate # Lookup text translations localize # Localize Date and Time objects to local formats

These have the aliases #t and #l

look at ActionView::Helpers::TranslationHelper

March 8, 2011 - (v2.3.8 - v3.0.5)
2 thanks

Dont use _delete

Most blog articles about accepts_nested_attributes_for, including the one from @mattsa and @annaswims, tell you to add a

'_delete' => 1

when you want a deletion checkbox, hidden attribute, etc.

But this stopped being true a while ago. This is just a “Watch Out!” Make sure you use

'_destroy' => 1

instead.

March 7, 2011 - (>= v3.0.0)
1 thank

:method => :delete, etc.

If you’re upgrading to Rails 3 you’ll need to make sure you include rails.js (which is in public/javascripts when you rails new someproject) You’ll need to include it after prototype. And you’ll need to have a 1.7 version of prototype.

When you do a

link_to "Delete", @some_obj, :method => "delete", :confirm => "Are you sure?"

Rails 3 will generate

<a href="some_obj/id" data-confirm="Are you sure?" data-method="delete">Delete</a>

rails.js will creates observers that convert that into a form.

Be aware that this probably won’t work as a link from inside a form (since forms in forms isn’t valid).

March 3, 2011 - (v3.0.0 - v3.0.5)
0 thanks

TimeZone in ActiveSupport

This seems to return ActiveSupport::TimeZone and not ::TimeZone as of v.3.0.0 and later.

March 3, 2011
1 thank

String#crypt uses your platform's native implementation

Which cipher types (specified through the salt argument) are available will depend on what your platform natively supports. It should be noted that OSX up to at last 10.6 only provides the regular DES cipher. On most Linux platforms, however, you should have access to the following:

ID  | Method
---------------------------------------------------------
1   | MD5
2a  | Blowfish (not in mainline glibc; added in some
    | Linux distributions)
5   | SHA-256 (since glibc 2.7)
6   | SHA-512 (since glibc 2.7)

So on OSX, you might have:

ruby-1.9.2-p180 :001 > "password".crypt("$6$somesalt")
 => "$6FMi11BJFsAc" 

But on Linux, you’ll get:

irb(main):001:0> "password".crypt("$6$somesalt")
=> "$6$somesalt$A7P/0Yfu8RprY88D5T1n.xKT749BOn/IXBvmR1gXZzU7imsoTfZhCQ1916CB7WNX9eOOeSmBmmMrl5fQn9LAP1"

For more information on what your platform supports, see `man crypt`

March 3, 2011
6 thanks

Using namespaces

If you are using a namespace in your routes.rb, for example:

namespace :admin do
  resources :products
end

then you can:

url_for([:admin, @product])

and:

url_for([:edit, :admin, @product])
March 3, 2011
0 thanks

Agree with Oleg

Yes, the only way round this seems to be to code e.g:

postArgs = { ‘table[field]’ => value, ‘table[f2]’ => v2 }

after the fashion of the browsers form definition.

This lets you do nested attributes as well, e.g: postargs[‘table[children_attributes[0][field]’] = value

March 3, 2011
0 thanks

Perfectly applicable

@rkh You would be correct if this code had occurred in a subclass who’s parent method was being overridden.

However, defining the method in this manner is completely removing the old method - as if you had written code like this:

class MyClass
  def do_something
    puts "We're doing some stuff here"
  end

  def do_something
    puts "The old do_something method no longer exists!"
  end
end

MyClass.new.do_something
# => "The old do_something method no longer exists!"

Of course this is non-sensical. But the idea is that you have either included a module, or monkey-patched an already existent class, and completely replaced the old method. super(*args) will not work