Flowdock

Recent notes

RSS feed
October 15, 2009
4 thanks

Have check_box checked by default

In addition to comment below, you can make a column with default value so in your forms it will be enabled by default and behave correctly with validation errors unlike :checked => true

in your migration

add_column :accounts, :ssl_enabled, :boolean, :default => 1
October 15, 2009
2 thanks
October 14, 2009
2 thanks

build_association deletes existing dependent record

Surprisingly (at least I was surprised), when an associated record exists, the build_association method immediately NULLs the foreign key in the database.

So if you write a singleton “new” action for the association in the obvious way (calling build_association), then just visiting the page will disconnect an existing associated record. This violates the principle that a GET request shouldn’t affect the database.

To avoid this, you can check for an existing association first, and redirect to the show action.

October 12, 2009
0 thanks

Use it to solve FixtureClassNotFound errors.

If you are using a non standard table name by means of set_table_name in your model:

class MyClassName < ActiveRecord::Base
  set_table_name "mytablename"
end

then you will get FixtureClassNotFound errors when you try to use fixtures in you unit tests. To solve this use set_fixture_class inside your test:

require 'test_helper'
class MyClassNameTest < ActiveSupport::TestCase
  set_fixture_class :mytablename => MyClassName  
end

and rename your fixture file to mytablename.yml

October 10, 2009
2 thanks

Example

[5,6,7].each_with_index do |x,i|

puts "#{i} -> #{x}"

end

Outputs: 0 -> 5 1 -> 6 2 -> 7

October 9, 2009
0 thanks

Case-insensitive comparison

For a case-insensitive comparison, use String#casecmp

October 7, 2009
4 thanks

Hash#without

Here’s a small helper for doing the “opposite” of this method:

class Hash
  def without(*keys)
    cpy = self.dup
    keys.each { |key| cpy.delete(key) }
    cpy
  end
end

h = { :a => 1, :b => 2, :c => 3 }
h.without(:a)      #=> { :b => 2, :c => 3 }
h.without(:a, :c)  #=> { :b => 2 }
October 7, 2009 - (>= v2.3.2)
3 thanks

Streaming XML with Builder

To generate larger XMLs, it’s a good idea to a) stream the XML and b) use Active Record batch finders.

Here’s one way of doing it:

def my_action
  @items = Enumerable::Enumerator.new(
    Item.some_named_scope,
    :find_each,
    :batch_size => 500)

  respond_to do |format|
    format.xml do
      render :text => lambda { |response, output|
        extend ApplicationHelper

        xml = Builder::XmlMarkup.new(
          :target => StreamingOutputWrapper.new(output),
          :indent => 2)
        eval(default_template.source, binding, default_template.path)
      }
    end
  end
end

The Builder template does not need to be modified.

October 5, 2009
0 thanks

Using argument version in ruby < 1.8.7

The argument to this method was added in Ruby 1.8.7. If you want to use this form in an earlier version, you must instead use the slice! method.

It is mentioned up in the docs, but here it is again for reference:

# Ruby >= 1.8.7
p = list.pop(n)

# Ruby < 1.8.7
p = list.slice!(-n, n)
October 5, 2009
2 thanks

collect/map

If you’d like to use this method for something like Enumerable#collect, you are looking at the wrong place. This method will return the initial integer, not the values from the block.

a = 20.times { |n| n * 2 } #=> 20

Instead, use Range#collect:

a = (0...20).collect { n * 2 }
October 5, 2009
2 thanks

Use camelize with singular words

To make the business example work, use camelize instead of classify:

"business".camelize     # => "Business"
October 5, 2009
0 thanks

Shortcut with %

@tordans for multiple args wrap the args in an array

October 3, 2009
0 thanks

Shortcut with %

Thanks iamcata, that works :). And I finally found the right place to put this comment: http://apidock.com/ruby/String/%25#726-Use-it-with-HAML

October 3, 2009
1 thank

Use it with HAML

Like Henrik pointed out <a href=“http://henrik.nyh.se/2008/01/surround-helper-alternative-in-haml”>in his blogpost, this method is particulary useful when using HAML (http://haml-lang.com/) in Rails.

Instead of usind the HAML-Helper ‘surround’ (etc) you can just write

= "(%s)" % link_to("Edit", ...)

Or with two Arguments:

= "(%s, %s)" % ["Edit", "Delete"]

Thanks very much, Henrik!

October 3, 2009
0 thanks

sort_by

array.sort_by {|element| [element.foo, element.bar.name, element.baz]}

Taken from http://redcorundum.blogspot.com/2006/10/using-sortby-instead-of-sort.html

October 2, 2009
1 thank

Shortcut

You can try:

“(%s %s)” % [“foo”, “bar”]

October 2, 2009
2 thanks

Making ActiveRecord models readonly

To force an ActiveRecord model to be read only you can do something along these lines:

class DelicateInfo < ActiveRecord::Base

 def readonly?
  true
 end

end

When you try to save the model it will raise an ActiveRecord::ReadOnlyRecord exception:

info = DelicateInfo.first
info.save # => ActiveRecord::ReadOnlyRecord

Note, however, that destroy and delete will still work on the model unless you intercept those calls

October 2, 2009
5 thanks

form_tag with named route and html class

<% form_tag position_user_card_path(@user, card), :method => :put, :class => ‘position-form’ do %>

October 1, 2009
0 thanks

This code prevent's frome redirect_to(:back) looping

Prevent redirect_to(:back) looop

begin

# loop check
if session[:last_back] != request.env['HTTP_REFERER']
  redirect_to(:back)
  session[:last_back] = request.env['HTTP_REFERER']
else
  # raise on error
  raise ActionController::RedirectBackError
end

rescue ActionController::RedirectBackError

# fallback on loop or other :back error
redirect_to(:action => :index)

end

October 1, 2009
0 thanks

ActiveResource validation is a little different

Given the following model on the remote end:

class Person < ActiveRecord::Base
 validates_presence_of :first_name, :last_name, :email
end

And this ActiveResource on the client end:

class Person < ActiveResource::Base
 self.site = "http://api.people.com:3000/" 
end

Validation messages will only be returned after an attempted save call on the client end - eg:

person = Person.new( :first_name => 'Billy', :emails => "william@anotherplanet.co.za" )
person.valid?                 # => true
person.errors.full_messages   # => []
person.save                   # => false
person.valid?                 # => false
person.errors.full_messages   # => ["Last name can't be empty"]

In ActiveResource::Base it is suggested that you can perform client site validation with something like this:

class Person < ActiveResource::Base
 self.site = "http://api.people.com:3000/"
 protected
  def validate
   errors.add("last name", "can't be empty") if last_name.blank?
  end
end
October 1, 2009
0 thanks

Update attributes on mulitple models

Updates attributes on multiple models, saves each if validations pass.

def update_multiple

  @items = Item.find(params[:item_ids])
  @items.each do |item|
    item.attributes = params[:item].reject { |k,v| v.blank? }
  end
  if @items.all?(&:valid?)
    @items.each(&:save!)
    flash[:notice] = "Updated items!"
    redirect_to items_path
  else
    flash[:notice] = "Please enter valid data."
    render :action => 'edit_multiple'
  end
end
September 30, 2009
2 thanks

See also: ActiveRecord::Base#increment

This is a class-level method. For the instance-level equivalent see: ActiveRecord::Base#increment

item = Item.find(1)
item.foo_count # => 0
Item.increment_counter(:foo_count, 1)
item.foo_count # => 0
item.reload
item.foo_count # => 1
item.increment(:foo_count)
item.foo_count # => 2
September 29, 2009
1 thank

Passing parameters to before_filter

I’ve found on the net 2 ways to pass parameters to before_filter:

method 1:

before_filter do |c|
c.class.module_eval do
private
def custom_filter
authorize(args)
end
end
end
before_filter :custom_filter

method 2:

before_filter do |c|
c.send(:authorize, args)
end
September 28, 2009
1 thank

Shortcut

According to http://henrik.nyh.se/2008/01/surround-helper-alternative-in-haml there is a short version for sprintf:

“(%s)” % “foo” is the same as sprintf(“(%s)”, “foo”)

Can someone who knows write more about this here? How do I work with multiple strings? Is this even possible? “(%s %t)” % “foo”, “bar” does not work.

September 24, 2009 - (>= v2.2.1)
0 thanks
September 24, 2009 - (>= v2.2.1)
0 thanks
September 24, 2009 - (>= v2.2.1)
0 thanks
September 24, 2009 - (>= v2.2.1)
0 thanks
September 24, 2009 - (>= v2.2.1)
0 thanks
September 24, 2009 - (>= v2.2.1)
0 thanks