Flowdock

Recent notes

RSS feed
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
1 thank

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
5 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)
0 thanks
March 23, 2011 - (>= v3.0.0)
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)
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)
3 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)
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
8 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
1 thank

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

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

you need use raw

in rails3

select_tag “people”, raw(“<option>David</option>”)

March 1, 2011 - (<= v3.0.0)
2 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])
February 28, 2011
0 thanks

flags

from ‘man recvfrom’

The flags argument to a recv() function is formed by or'ing one or more of the values:

MSG_OOB        process out-of-band data
MSG_PEEK       peek at incoming message
MSG_WAITALL    wait for full request or error

The MSG_OOB flag requests receipt of out-of-band data that would not be received in the normal data stream.  Some protocols place expedited data at the head of the
normal data queue, and thus this flag cannot be used with such protocols.  The MSG_PEEK flag causes the receive operation to return data from the beginning of the
receive queue without removing that data from the queue.  Thus, a subsequent receive call will return the same data.  The MSG_WAITALL flag requests that the opera-
tion block until the full request is satisfied.  However, the call may still return less data than requested if a signal is caught, an error or disconnect occurs, or
the next data to be received is of a different type than that returned.
February 23, 2011 - (>= v3.0.0)
1 thank

Works with scoped too

It’s also available to use after scope chain too, like in any other AR action, for example:

User.where('age > 69').delete_all
February 22, 2011
7 thanks

Passing arguments to block

To pass arguments to block being captured, just list them as capture method params. I.e.

def export(exportable, export_klass, options={}, &block)
  result = ""
  #...
  if block_given?
    result += capture(my_custom_var_i_want_to_pass_to_block, &block)
  end
  result
end

Then simply…

 <%= export(@a, @b) do |my_custom_var| %>
  <% if my_custom_var.nil? %>
    My custom var is nil!!!
  <% end %>
<% end %>
February 22, 2011 - (v1_8_7_72)
0 thanks

counts the length of non-uncode characters.

jlength counts the non-unicode characters in a string to its actual length. Otherwise rails treat as 5 characters.

February 21, 2011 - (>= v3.0.0)
8 thanks

case-insensitive uniqueness

For case-insensitive uniqueness:

validate :username, :uniqueness => {:case_sensitive => false}
February 17, 2011
2 thanks

You can call it with an { :on => ~~~ } as the last argument

For example:

validate :must_be_friends, :on => :create
February 15, 2011 - (v3.0.0)
0 thanks

No type cast to Float

In Rails 3 the returned value will be type cast to the column’s type and not Float. So when calculating average on a column the column’s type need to be float, the result will be truncated otherwise.

February 10, 2011
0 thanks

Eliminates Double Slashes

Also eliminates inadvertent double slashes:

path = '/uploads/art/'
file = '/pic.jpg'
File.join(path, file) # => '/uploads/art/pic.jpg'
February 10, 2011 - (<= v2.3.8)
3 thanks

Undocumented callbacks

Not sure why this isn’t documented… there are callbacks for before/after_add and before/after_remove. Example

has_many :things, :after_add => :set_things, :after_remove => :remove_things

def set_things(thing)
  ...
end
def remove_things(thing)
  ...
end