Recent notes
RSS feedHow 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)
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
Timestamps
Note that ActiveRecord will not update the timestamp fields (updated_at/updated_on) when using update_all().
Rails 3 validation methods
In rails 3 these have been moved to ActiveModel::Validations::HelperMethods
Method not deprecated
at least not according to the Rails release notes: http://edgeguides.rubyonrails.org/3_0_release_notes.html#validations
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
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)
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
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.
: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).
TimeZone in ActiveSupport
This seems to return ActiveSupport::TimeZone and not ::TimeZone as of v.3.0.0 and later.
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`
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])
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
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
How to deal with Missing host to link to!
You just need to define default_url_options[:host] in your class. The easiest way to do it:
class SomeClass include ActionController::UrlWriter default_url_options[:host] = YourApp::Application.config.action_mailer.default_url_options[:host] def some_method some_superb_url(maybe_even_some_variable_here) end end
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])
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.
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
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 %>
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.
case-insensitive uniqueness
For case-insensitive uniqueness:
validate :username, :uniqueness => {:case_sensitive => false}
You can call it with an { :on => ~~~ } as the last argument
For example:
validate :must_be_friends, :on => :create
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.
Eliminates Double Slashes
Also eliminates inadvertent double slashes:
path = '/uploads/art/' file = '/pic.jpg' File.join(path, file) # => '/uploads/art/pic.jpg'
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