Flowdock

Recent notes

RSS feed
July 23, 2012
1 thank

Long-wanted functional extension

This is pretty nice method allowing you to build stuff in a functional way.

Lets say you want to build a hash from an array, keyed by array object, where each value is the number of same objects in the array.

# imperative style :-P

h = Hash.new(0)
[1, 3, 2, 3, 1, 3].each { |i| h[i] += 1 }
h # => {1=>2, 3=>3, 2=>1} 

# functional style, using inject. Note that you need to explicitly return the accumulator in the end

[1, 3, 2, 3, 1, 3].inject(Hash.new(0)) { |a, i| a[i] += 1; a } 
# => {1=>2, 3=>3, 2=>1} 

# using each_with_object. Note the reversed block params - accumulator is the last parameter. 
# Mnemonic: consistent with each_with_index, where object is the first parameter

[1, 3, 2, 3, 1, 3].each_with_object(Hash.new(0)) {|i, a| a[i] += 1}
# => {1=>2, 3=>3, 2=>1} 
July 23, 2012
0 thanks

Replacement

Replacement

# Method using returning can replaced
def foo
  returning Hash.new do |h|
    h[:foo] = "bar"
  end
end
# By method using tap  
def foo
  Hash.new.tap do |h|
    h[:foo] = "bar"
  end
end
July 20, 2012
1 thank

Skipping validation - follow up

For Rails 2.x use #save(false) for Rails 3.x use #save(:validate => false)

July 20, 2012
0 thanks

Set ids when using a collection of values (cont.)

Regarding schmidt’s post.

The following will not have the expected behavior:

<% Car.each do |c| %>
  <%= check_box_tag "car_ids[]", c.id, :id => "car_ids_#{c.id}" %>
<% end %>

But, if you put the “checked” option to false (or true), it will.

<% Car.each do |c| %>
  <%= check_box_tag "car_ids[]", c.id, false, :id => "car_ids_#{c.id}" %>
<% end %>
July 20, 2012 - (v3.0.0 - v3.2.3)
2 thanks

Changing the Message

For Change the default message:

Code example

validates :invoice_number, :presence => {:message => 'The invoice number must be informed.'}
July 19, 2012
0 thanks

Assignment using 'key: value'

Another shorthand way of assigning key, value pairs:

Hash[one: 1, two: 2] #=> {:one=>1, :two=>2}
July 12, 2012
1 thank

conditional rescue_from

Would it be possible to do something like:

rescue_from Exception, :with => my_handler, :unless => request.local?
July 10, 2012
0 thanks

Checking content_for

@tordans You asked your question 3 years ago, but in any case, should anyone have that same issue, you can manage that with:

- unless content_for(:footer).blank?
  yield(:footer)
- else
  == render "layouts/footer_big"

content_for(:x) defaults to an empty string, that’s why you need to check for blank? not nil?.

July 9, 2012
0 thanks

this has been deprecated; replace with Memoist

In Rails 3.2, memoize has been deprecated. In edge Rails, it has been removed.

The commit when it was deprecated: http://github.com/rails/rails/commit/36253916b0b788d6ded56669d37c96ed05c92c5c

A Stack Overflow question about this change: http://stackoverflow.com/q/9132197/578288

I personally disagree with the removal of memoize, and don’t recommend using the `||=` pattern Rails now suggests. The exception is if your entire program only memoizes something once or twice, so it’s not worth including a gem for.

The easiest way to keep using memoize is to use the Memoist gem (http://github.com/matthewrudy/memoist , http://rubygems.org/gems/memoist), which is a simple extraction of ActiveSupport::Memoizable into its own gem.

June 28, 2012
0 thanks

see also – similar methods

See also DateTime#strftime and Date#strftime . (They work similarly, but have different APIdock notes.)

June 28, 2012
0 thanks

see also – similar methods

See also Time#strftime and DateTime#strftime . (They work similarly, but have different APIdock notes.)

June 28, 2012
0 thanks

see also – similar methods

See also Time#strftime and Date#strftime . (They work similarly, but have different APIdock notes.)

June 25, 2012 - (<= v2.3.8)
0 thanks

Adding Additional Parameters to form_for

If you want to add additional parameters to the form_for helper, but still want to use one form for both your “create” and your “update” actions, you can add the additional parameters to the :url option, but you need to omit the :controller and :action keys.

form_for(@user, :url => {:param1 => "value1", :param2 => "value2"}) do |f|

or

form_for([@post, @comment], :url => {:param1 => "value1", :param2 => "value2"}) do |f| 

where param1 and param2 are not :controller or :action

June 22, 2012 - (v1_8_6_287 - v1_9_3_125)
2 thanks

Test if an array is included in another

Array

class Array
   def included_in? array
     array.to_set.superset?(self.to_set)
   end
end

[1,2,4].included_in?([1,10,2,34,4]) #=> true
June 20, 2012 - (v2.2.1 - v3.2.3)
1 thank

Another usage example

given: order active record class with “state” string field

class Order < ActiveRecord::Base
  def state
    @state ||= ActiveSupport::StringInquirer.new(read_attribute(:status))
  end
end

order = Order.new(state: "initial")
order.state.initial? #=> true
order.state.paid? #=> false
June 20, 2012 - (>= v3.0.0)
1 thank

add_to_base in Rails 3

In addition to stevo’s note, in Rails 3 you can also do:

model_instance.errors.add(:base, "Msg") 
June 15, 2012 - (<= v3.2.3)
0 thanks

Month-first date string no longer parses correctly

The following date format won’t be parsed correctly:

'06/15/2008'.to_date 

Use this instead:

Date.strptime("6/15/2012", '%m/%d/%Y')
June 13, 2012
0 thanks

Example of usage

e.g.

str = ActiveSupport::StringInquirer.new('test')

str.test? # => true
str.foobar? # => false
June 11, 2012
0 thanks

more_than? instance method

Over the weekend I kept running into instances where I was writing code like this:

Code example

arr = ['hello', 'world']

if arr.length > 2
 # do stuff
else
 # do something else
end

So I ended up extending the core and adding an instance method of more_than?

Code example

class Array
  def more_than?(num)
    length > num
  end
end

Usage

arr = ['hello', 'world']
puts "Hello" if arr.more_than? 1
June 7, 2012 - (>= v3.2.3)
1 thank

:disable_with is deprecated

Or you can use this way:

<%= submit_tag "Login", data: { disable_with: "Please wait.." } %>
June 5, 2012
1 thank

:disable_with is deprecated

Since version 3.2.5 you should not use :disable_with.

Use this:

<%= submit_tag "Login", 'data-disable-with' => "Please wait.." %>
June 4, 2012
0 thanks

You can remove leading Zeros this way as well

By just adding a - symbol.

%-I %-d

June 4, 2012 - (v2.3.2 - v3.2.3)
0 thanks

This method does not work.

It’s an old problem, reported back in 2010, just reopened issue:

http://github.com/rails/rails/issues/6620

May 28, 2012
0 thanks

Accepted parameters for validate

Validate method also accepts :on and :if parameters. The default value for :on is :save, the other accepted values are :create and :update

class Comment
  include ActiveModel::Validations

  validate :must_be_friends, :on => :create, :if => Proc.new {|comment| some_condition}

  def must_be_friends
    errors.add(:base, "Must be friends to leave a comment") unless commenter.friend_of?(commentee)
  end
end
May 26, 2012 - (v1_9_3_125)
0 thanks

rindex with identically array elements

Code Example

a = [1,1,1]
a.rindex( a.min ) #=> 2
May 22, 2012
0 thanks

similar to clone

See the clone documentation. I see that ActiveRecord is moving from “clone” (3.0.9) to “dup” (?).

May 18, 2012
0 thanks

Beware nested with_options clobbers!

Careful:

with_options :foo => :bar do |something|
  something.with_options :foo => :baz do |inner|
    what_is(:foo)
  end
end

:foo will be :baz. It will not be [:bar, :baz], for example.

This bit me when trying to do nested with_options for validation where both had :if => something.

May 17, 2012
0 thanks

If you try to use :id as a non-primary-key field

If you’re using this so that you can repurpose :id for another use, it gets hairy: your ActiveRecord::Base subclass will still use :id to refer to your primary key, whatever it be named.

So when you call [my obj].id = 33, 33 is set as the value of your primary key, not your :id attribute!

May 17, 2012
0 thanks

Starts with capital letter alternative

Just adding an anchor to the regular expression seems simpler (and was faster in my benchmarks, not that that matters much):

'Abracadabra' =~ /^[A-Z]/