Flowdock

Recent notes

RSS feed
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
5 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
February 9, 2011 - (<= v2.3.8)
0 thanks

some gotchas

Works

named_scope :public, :conditions => "public = true"

Works

PUBLIC_CONDITIONS = "public = true"
named_scope :public, :conditions => SomeModel::PUBLIC_CONDITIONS

Works

named_scope :public, lamba { {:conditions => SomeModel.public_conditions} }
def self.public_conditions
  "public = true"
end

Doesn’t work

named_scope :public, :conditions => SomeModel.public_conditions
def self.public_conditions
  "public = true"
end
February 7, 2011
0 thanks

onchange attribute on a hidden field is useless

In the third example there is no sense to set onchange event since it will never happen…

February 7, 2011 - (v1.0.0 - v2.3.8)
0 thanks

If on Rails 3

If you’re on Rails 3, you should look into

http://apidock.com/rails/ActiveRecord/Relation/update_all
February 5, 2011 - (<= v2.3.8)
0 thanks

update_all (and delete_all) don't play nicely with default_scope

If you have

class Topic < ActiveRecord::Base
  default_scope :conditions => "forums.preferences > 1", :include => [:forum]
end

and you do a

Topic.update_all(...)

it’ll fail with

Mysql::Error: Unknown column 'forums.preferences' in 'where clause'

The work around for this is:

Topic.send(:with_exclusive_scope) { Topic.update_all(...) }

You can monkey patch this using this code (and requiring it in environment.rb or else where)

module ActiveRecordMixins
  class ActiveRecord::Base
    def self.update_all!(*args)
      self.send(:with_exclusive_scope) { self.update_all(*args) }
    end
    def self.delete_all!(*args)
      self.send(:with_exclusive_scope) { self.delete_all(*args) }
    end
  end
end
end

Then just you update_all! or delete_all! when it has a default scope.

January 28, 2011 - (>= v1_8_7_72)
1 thank

Passing a block with methods

Code example

Google = Struct.new(:address) do
  def latitude
    -1
  end

  def longitude
    -2
  end

  def with_address
    "with #{address}"
  end
end

g = Google.new("Some Addres")

puts g.address
puts g.latitude
puts g.longitude
puts g.with_address

Result

# >> Some Addres
# >> -1
# >> -2
# >> with Some Addres
January 27, 2011
1 thank

Dont reject! on the yielded batch

If you remove any values from the batch, the while loop in find_in_batches breaks even if there are additional batches:

People.count # => 3000

People.find_in_batches do |peeps|
  peeps.reject!(&:bad?)
  # ... more operations on peeps
  puts 'Tick'
end

Running the above code, you’ll only see Tick once. Rather use:

People.find_in_batches do |peeps|
  peeps = peeps.reject(&:bad?)
  # ... more operations on peeps
  puts 'Tick'
end

You should see Tick outputted 3 times

January 26, 2011 - (>= v3.0.0)
2 thanks

Use this for validatating nested forms

When you create a nested form, and want the main object to validate all nested models, you should make all the nested models dirty or validations will not run upon them.

class Order < ActiveRecord::Base
  has_many :order_lines
  accepts_nested_attributes_for :order_lines

  before_validation :mark_order_lines_as_changed

  private
  def mark_order_lines_as_changed
    order_lines.each(&:updated_at_will_change!)
  end
end
January 24, 2011
0 thanks

Does not respond to ajax call

I inherited some code that used form_remote_tag. send_file and send_data did not work.

Changing from from_remote_tag to form_tag and all worked as expected.

January 24, 2011
0 thanks

you probably want:

Rails.env

or possibly:

ActionController::TestRequest.new (which has a demo of how to set env vars on a controller test)

January 21, 2011 - (<= v2.3.8)
0 thanks

Doesn't work for associations.

This method relies on #blank? to determine if the attribute is valid.

When you call #blank? on an ActiveRecord object, it returns true as long as there are no changes to the object.

So you can validate the base attribute (i.e.: product_id), but you’ll have no guarantee that it points to a valid record without your own validator.

January 18, 2011
2 thanks

Common AJAX options

See the documentation for link_to_remote to see the common AJAX options, like :before and :completed.

January 18, 2011
0 thanks

Grouping

Person.sum(:age, :group => “sex”) # =>[[“male”,2500],[“female”,2200]]

January 18, 2011
2 thanks

Grouping

Person.sum(:age, :group => “sex”) # =>[[“male”,2500],[“female”,2200]]

January 15, 2011 - (v2.3.2 - v2.3.8)
0 thanks

Parameter extraction logic changed in Rails 2.3!

What is documented here about Rails parameter extraction always getting the first occurrence of a key is apparently incorrect (in Rails 2.3 it gets the last occurrence).

See the following email thread on [rubyonrails-core]:

http://www.mail-archive.com/rubyonrails-core@googlegroups.com/msg08719.html

I quote:

> In the docs for ActionView::Helpers::FormHelper#check_box, when
> discussing why the method adds a hidden input tag _after_ the checkbox
> tag, it says
>
>  "...Rails parameters extraction always gets the first occurrence of
> any given key..."
>
> I'm not sure this is still the case.

Indeed it changed in 2.3 but unfortunately the patch didn't update the
docs. We noticed this a few days ago, they are correct now in edge.
January 11, 2011
5 thanks

Disable STI

I had to add “self.inheritance_column” as opposed to simply “inheritance_column” to get this to work.

Code example

class MyModel < ActiveRecord::Base
  # disable STI
  self.inheritance_column = :_type_disabled
end
January 6, 2011 - (>= v3.0.0)
2 thanks

Accessing URL helpers in Rails 3

I’ve been upgradings an app to Rails 3 and it took me a bit to find this-

If you were using

include ActionController::UrlWriter

to get the url helpers in rails 2, you should switch to

include Rails.application.routes.url_helpers

for Rails 3

From: http://snipplr.com/view/37063/to-access-url-helpers-urlfor-etc-from-rails-console-rails-3/

January 6, 2011
0 thanks

Adding initialization parameters for the relevant cache store

To configure caching of f.ex. a :mem_cache_store you can pass additional parameters just after the cache type symbol:

ActionController::Base.cache_store = \
  :mem_cache_store, 'a.example.org:11211', 'b.example.org:11211'

all parameters after the cache type symbol will be passed on to the corresponding cache store constructor.

January 5, 2011
0 thanks

Passing in parameters

If you want to pass in parameters you can do it like this:

User.get(:find_by_name, headers = {:name => "bob"})
=> /users/find_by_name.xml?name=bob

For nested routes…

routes.rb

resources :companies do
  resources :users do
    member do
      get :find_by_name
    end
  end
end

In your api code…

class User < ActiveResource::Base  

  self.site = "/companies/:company_id"

  def self.find_by_name(name, company_id)
    User.get(:find_by_name, headers = {:name => name, :company_id => company_id}
  end
end

Then doing…

User.find_by_name("bob", 1)

Would call

companies/1/users/find_by_name.xml?name="bob"

This works in Rails 3.1 - not sure about older versions (specifically I think the routes were done differently in < 3

January 3, 2011
0 thanks

Throw error after rollback

If you want to throw the exception after rolling back you can do something like this:

Company.transaction do
  user.save
  company.save
  x = 1/0
rescue
  exp = $!
  begin
    raise ActiveRecord::Rollback
  rescue
  end
  raise exp
end