Notes posted to Ruby on Rails
RSS feedThis method has been moved
This method has been moved to ActiveSupport::Inflector#demodulize
This method has been moved
This method has been moved to ActiveSupport::Inflector#foreign_key
This method has been moved
This method has been moved to ActiveSupport::Inflector#humanize
This method has been moved
This method has been moved to ActiveSupport::Inflector#inflections
This method has been moved
This method has been moved to ActiveSupport::Inflector#ordinalize
This method has been moved
This method has been moved to ActiveSupport::Inflector#singularize
This method has been moved
This method has been moved to ActiveSupport::Inflector#tableize
This method has been moved
This method has been moved to ActiveSupport::Inflector#titleize
This method has been moved
This method has been moved to ActiveSupport::Inflector#underscore
This method has been moved
This method has been moved to ActiveSupport::Inflector#dasherize
This method has been moved
This method has been moved to ActiveSupport::Inflector#constantize
This method has been moved
This method has been moved to ActiveSupport::Inflector#classify
This method has been moved
This method has been moved to ActiveSupport::Inflector#camelize
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
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', ':') %>
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
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")
: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.
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'
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.
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 )
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} %>
How not to find an element
assert_select ‘div’, :count => 0
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
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"]
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();"
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
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) %>
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) %>