Flowdock

Notes posted to Ruby on Rails

RSS feed
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

August 21, 2009
2 thanks

Passing parameters to custom formbuilders

If you implement your own formbuilder, the options passed are available as @options inside your formbuilder. If you want those configuration options passed to all builders in the fields_for sections, use the following code in your form builder:

def fields_for_with_options(record_or_name_or_array, *args, &block) options = args.extract_options! fields_for_without_options(record_or_name_or_array, *(args << options.merge(@options)), &block) end alias_method_chain :fields_for, :options

Usage:

form_for @my_object, :builder => MyCustomFormbuilder, :some_setting => :cool
August 19, 2009 - (v2.1.0 - v2.3.2)
0 thanks

Gotcha with class_inheritable_accessor and cloneing the attribute values

The key thing to note from post is that class_inheritable_accessor copies the value from the parent class at inherit time. So, if you are setting a default value of an array and doing something like the following you might end up with unintended results:

>> A.class_inheritable_foo << 'from a'
=> ["from a"]
>> B.class_inheritable_foo << 'from b'
=> ["from a", "from b"]
>> C.class_inheritable_foo << 'from c'
=> ["from a", "from b", "from c"]

However, if you use the form:

class << self
  def class_instance_foo
    @class_instance_processors ||= []
  end
end

The original values aren’t copied from the parent class when you reference the class for the first time:

>> A.class_instance_foo << 'from a'
=> ["from a"]
>> B.class_instance_foo << 'from b'
=> ["from b"]
>> C.class_instance_foo << 'from c'
=> ["from c"]
August 18, 2009
2 thanks

Auto-submitting select tag

If you want your form to be submitted when user selects something, use:

:onchange => "this.form.submit();"

For example:

select_tag "people", "<option>David</option>", :onchange => "this.form.submit();"
August 18, 2009
0 thanks

Using custom object via :object

Sometimes you need use select not only with @object as by default. For example if you have helper method like :

def select_parent_for(page)
  select(:page, :parent_id, Page.all.collect{|p| [p.name, p.id]} ) # <--- mistake!
end

In selected line you will use @page instead parameter of method page.

The options has parameter :object (and all form helpers has such parameter)

Solution:

def select_parent_for(page)
  select(:page, :parent_id, ..., :object => page)
end
August 17, 2009
2 thanks

Time in fixtures

When creating fixtures you should use this method to set created_at/updated_at timestamps correctly:

eg:

This won’t work as expected (created_at/updated_at will be nil) a

one:
  episode: active1
  play_id: 1
  play_time: 20
  country: United Kingdom
  created_at: <%= Time.parse('22:00 14 Aug 2009') %>
  updated_at: <%= Time.parse('22:00 14 Aug 2009') %>

but this will work as expected:

one:
  episode: active1
  play_id: 1
  play_time: 20
  country: United Kingdom
  created_at: <%= Time.parse('22:00 14 Aug 2009').to_s(:db) %>
  updated_at: <%= Time.parse('22:00 14 Aug 2009').to_s(:db) %>
August 17, 2009
1 thank

Time in fixtures

When creating fixtures you should use this method to set created_at/updated_at timestamps correctly:

eg:

This won’t work as expected (created_at/updated_at will be nil) a

one:
  episode: active1
  play_id: 1
  play_time: 20
  country: United Kingdom
  created_at: <%= Time.parse('22:00 14 Aug 2009') %>
  updated_at: <%= Time.parse('22:00 14 Aug 2009') %>

but this will work as expected:

one:
  episode: active1
  play_id: 1
  play_time: 20
  country: United Kingdom
  created_at: <%= Time.parse('22:00 14 Aug 2009').to_s(:db) %>
  updated_at: <%= Time.parse('22:00 14 Aug 2009').to_s(:db) %>
August 16, 2009
1 thank

Small notice about recognize urls with specific HTTP verbs

This is wrong ruby syntax:

assert_recognizes {:controller => 'items', :action => 'create'}, {:path => 'items', :method => :post}

Parentheses are obligatory in this case:

assert_recognizes({:controller => 'items', :action => 'create'}, {:path => 'items', :method => :post})
August 15, 2009
0 thanks

To find element ant not to find element

If you want to see administration panel:

assert_select "div.admin-panel"

But if you want to NOT see administration panel just write:

assert_no_tag 'div', :attributes => {:class => 'admin-panel'}
August 13, 2009
2 thanks

With multiple parameters

Example

remote_function(
   :url => some_remote_function_path, 
   :with => "'key1='+$('elem_id').value +'&key2='+$('elem_id').value+ '&this_elem_value='+value"
) 
August 13, 2009 - (>= v2.3.2)
3 thanks

with_exclusive_scope example by Ramon broken in latest Rails

The example Ramon gave works within the model itself, i.e.

class Article
  def closed
    with_exclusive_scope { find(:all) }
  end
end

However, from what I can see, this approach does not work within a controller. You may be wanting to use

Article.with_exclusive_scope { find(:all) }  #=> "SELECT * FROM 'articles'

But it will error out about find(:all) not existing on ArticlesController. To get around this, you must now do

Article.with_exclusive_scope { Article.find(:all) }  #=> "SELECT * FROM 'articles'

In otherwards, find(:all) isn’t being executed in the scope of the model, but in the controller in which its called.

Took me a minute or two to find out, so I thought I’d let others know.

August 12, 2009
0 thanks

Current Database Name: Sqlite version

Get the current database name when using Sqlite:

ActiveRecord::Base.connection.instance_variable_get(:@config)[:database].split('/').last
August 10, 2009
0 thanks

Content type for emails with attachments

Be aware that if you want to send emails with attachments, you probably want to use the content type multipart/mixed for the overall email.

The MIME time multipart/alternative is intended for emails where each part is a different representation of the same message.

After following the 2.3.2 documentation we used multipart/alternative to attach files to our mails, however this then caused Hotmail to ignore the attachments. It turns out it thought they were all alternative versions of the HTML content (which it could already display, so the alternatives weren’t necessary)

August 8, 2009
2 thanks

Re: Validate an optional URL field

Actually it’s easier to use validates_format_of for this task. Please refer to the comments under the doc.

August 7, 2009
7 thanks

Join multiple tables

It’s easy to join multiple tables too. In this case we have:

class Article
  belongs_to :feed
end

class Feed
  has_many :articles
  belongs_to :source
end

class Source
  has_many :feeds
  # t.bool :visible
end

You can search articles and specify a condition on the sources table.

Article.find(:all, 
  :conditions => { :feeds => { :sources => { :visible => true }}}, 
  :joins => [:feed => :source],
August 7, 2009
0 thanks
August 7, 2009
0 thanks

Most common use case

Most common use case is probably:

Rails.cache.fetch "some key" do
  compute some value
end

This computes some value and caches it. Subsequent invocations will return cached value (as long as it is still cached).

August 7, 2009
2 thanks

Documentation

This method only returns a cache manager object of sorts, to see what you can do with it, see ActiveSupport::Cache::Store.

August 6, 2009
4 thanks

Documentation bug

When adding the :target option, the documentation states that you should user :href_options like so:

auto_link(post_body, :href_options => { :target => '_blank' })

However, I could only get it to work using :html instead:

auto_link(post_body, :html => { :target => '_blank' })

I’m using Rails 2.2.2, but I believe that this also happens for more recent version .

August 6, 2009
1 thank

*Described above

The documentation is referring to the module documentation: ActionController::Cookies

August 4, 2009 - (>= v2.2.1)
1 thank

Binding parameter deprecated in > 2.2

Supplying the binding argument produces a deprecation warning in 2.2 and newer:

DEPRECATION WARNING: The binding argument of #concat is no longer needed. Please remove it from your views and helpers.

August 3, 2009
0 thanks

Separating date and time

Option :datetime_separator can be set too. Default is ‘ &mdash; ’

July 30, 2009
2 thanks

How to set default value to NULL

To set default value to NULL you can use change_column method instead, for example:

change_column :suppliers, :qualification, :string, :default => nil

Just make sure you don’t change data type accidentally ;-)

July 30, 2009 - (>= v2.3.2)
0 thanks

can we use both sortable_element and drop_recieving_element on same list

I had a sortable_element that was also a drop_receiving_element. element it’s dropping while dropping element into selected container ,but not element dragging is not viewble to end users. it’s dragging only in sortable list area. but mu droppble contanier is another one.i used scroll => true in sortable_element . but its not working for sorting and dropping element into contianer. could u letme know how to use both methods on same list