Flowdock

Notes posted to Ruby on Rails

RSS feed
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 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
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)
2 thanks
September 24, 2009 - (>= v2.2.1)
0 thanks
September 24, 2009 - (>= v2.2.1)
0 thanks
September 18, 2009 - (>= v2.3.2)
0 thanks

Regenerate the JavaScript after each RJS call

RISCfuture - I had trouble using sortable_element_js in my rjs (javascript error when I used options), but had success with page.sortable(‘the_id’,{a_hash_of_my_options}) in my rjs

September 14, 2009
6 thanks

Pluralize Without Count

Helper method that returns the word without the count.

application_helper.rb

def pluralize_without_count(count, noun, text = nil)
  if count != 0
    count == 1 ? "#{noun}#{text}" : "#{noun.pluralize}#{text}"
  end
end

Example usage:

_form.html.erb

<%= pluralize_without_count(item.categories.count, 'Category', ':') %>
September 9, 2009
3 thanks

Will discard any order option

order_by(:created_at).find_each == FAIL!!!

class ActiveRecord::Base
  # normal find_each does not use given order but uses id asc
  def self.find_each_with_order(options={})
    raise "offset is not yet supported" if options[:offset]

    page = 1
    limit = options[:limit] || 1000

    loop do
      offset = (page-1) * limit
      batch = find(:all, options.merge(:limit=>limit, :offset=>offset))
      page += 1

      batch.each{|x| yield x }

      break if batch.size < limit
    end
  end
end
September 9, 2009
2 thanks

Attachment's name

Files attached in a standard way are shown up as “noname”. You can specify any name by using the :filename key:

attachment :content_type => "application/pdf",
           :filename     => "Othersheet.pdf",
           :body         => File.read("example.pdf")
September 7, 2009
0 thanks

:popup gotcha in IE

If your popup title contains spaces or escaped HTML characters, Internet Explorer (at least 6/7) will not pop up a new window but open the link in the existing browser window.

September 6, 2009
0 thanks

Add last_week to core_extensions

If you want to implement last_week as posted by Mange, save it as:

lib/core_extensions.rb

class Date
  def last_week(day = :monday)
    days_into_week = { :monday => 0, :tuesday => 1, :wednesday => 2, :thursday => 3, :friday => 4, :saturday => 5, :sunday => 6}
    result = (self - 7).beginning_of_week + days_into_week[day]
    self.acts_like?(:time) ? result.change(:hour => 0) : result
  end
end

And add to:

config/environment.rb

require 'core_extensions'
September 1, 2009 - (>= v2.3.2)
1 thank

session expiration

If you need to set expiration period for sessions through all controllers in your application, simply add the following option to your config/intializers/session_store.rb file:

:expire_after => 60.minutes

If you need to set different expiration time in different controllers or actions, use the following code in action or some before_filter:

request.session_options = request.session_options.dup
request.session_options[:expire_after] = 5.minutes
request.session_options.freeze

Duplication of the hash is needed only because it is already frozen at that point, even though modification of at least :expire_after is possible and works flawlessly.

from - http://squarewheel.pl/posts/3

August 26, 2009
0 thanks

Passing an :object to the partial

For some reason the :object option is completely undocumented. Here’s an example usage.

# Renders the partial, making @new_person available through the local variable 'person'
render :partial => "person", :object => @new_person

(Credit goes to Catfish for the example, which I obtained from http://dev.rubyonrails.or/ticket/8518 )

August 26, 2009 - (v1.0.0 - v2.3.2)
2 thanks

sending an array of multiple options

To make sure that you’ll receive a array you should declare the name of the select with “[ ]” like that:

Example

<%= select_tag "users[]", options_for_select(@users.collect{|x| [x.name,x.id]}), {:multiple => :multiple, :size => 10} %>
August 21, 2009
1 thank

How not to find an element

assert_select ‘div’, :count => 0