Recent good notes
RSS feedDemo: select onchange invoke an ajax
select(“order”, “customer_id”, o.customer.collect {|c| [ c.label, c.id ] },
{:include_blank => true, :selected => o.customer_id }, :onchange => remote_function(:update => "message_id", :method => "put", :with => "'item=' + value", :url => { :controller => :orders, :action => :set_customer_id, :id => order.id}))
Documentation
Allows for reverse merging where its the keys in the calling hash that wins over those in the other_hash. This is particularly useful for initializing an incoming option hash with default values:
def setup(options = {}) options.reverse_merge! :size => 25, :velocity => 10 end
The default :size and :velocity is only set if the options passed in doesn‘t already have those keys set.
Rails 2.1 migrations
Things to take note of are the lack of ‘column spam’, which didn’t convey much semantic meaning. Also the combination of multiple fields per line with the same type.
references is also a nice helper to convey relationship information (t.references :role is equivilant to t.integer :role_id). references also takes another parameters, see the method for more details.
code
class CreateUsers < ActiveRecord::Migration def self.up create_table :users do |t| t.string :first_name, :last_name, :email t.text :address t.date :date_of_birth t.references :role t.timestamps end add_index :users, :email end def self.down drop_table :users end end
Better slug generation (essentially a to_param replacement)
Monkey Patching String
class String def slugify returning self.downcase.gsub(/'/, '').gsub(/[^a-z0-9]+/, '-') do |slug| slug.chop! if slug.last == '-' end end end
In a model, or wherever
def to_param # Don't need the id here if we're looking up the model by the stored slug. "#{id} #{title}".slugify end
Is it really deprecated?
I think the deprecation notice is in the wrong place, it is actually the instance method ActiveRecord::Validations#validate that has been deprecated.
The same applies to ActiveRecord::Validations#validate_on_create and ActiveRecord::Validations#validate_on_update: they have both been deprecated in favour of the class methods validate_on_create and validate_on_update.
helper method to partial
concat can be useful for rendering a block to a partial from a helper:
def block_to_partial(partial_name, options = {}, &block) options.merge!(:body => capture(&block)) concat(render(:partial => partial_name, :locals => options), block.binding) end
This would be particularly useful if you had some partial to help you out with rounded corners, for example. So, in your helper:
def rounded_corners &block block_to_partial("shared/rounded_corners", {}, &block) end
In your view you could have something like:
<% rounded_corners do -%> This text is surrounded by rounded corners <% end -%>
You would have to create some partial in
app/views/shared/rounded_corners.html.erb
And it would look something like:
<div class='c1'> <div class=c2> . . . <%= body -%> </div> </div>
Generate an observer
Generating an observer from the command line follows the usual pattern:
script/generate observer audit
This will create a model called:
app/models/audit_observer.rb
Where you declare before_destroy matters
Beware that where you declare a before_destroy callback matters if you have any “acts_as” type declarations, that also declare before_destroy callbacks. A good example is the acts_as_nested_set. If you specify acts_as_nested_set prior to your before_destroy, then acts_as_nested_set will go through and destroy all children first, then your callback will run (at which point children will be empty). Thus, if your before_destroy callback needs to examine the children, it will not work properly. Putting your before_destroy callback ahead of acts_as_nested_set or anything else that declares a before_destroy is key in such cases.
Required Reading
The details for using layout (such as possible values for the conditions hash) can be found in ActionController::Layout::ClassMethods.
Convert strings to Dates
Uses the undocumented Date._parse method. Some usage examples:
'06/15/2008'.to_date # => Sun, 15 Jun 2008 '20080615'.to_date # => Sun, 15 Jun 2008 '2008-06-15'.to_date # => Sun, 15 Jun 2008 'Sun, 15 Jun 2008'.to_date # => Sun, 15 Jun 2008
For more information
See Base class.
For more information
See ActiveMailer::Base.
List of statuses
You can view a full list of statuses at http://dev.rubyonrails.org/browser/trunk/actionpack/lib/action_controller/status_codes.rb.
head can be called with a symbol or a status code:
Using head with a symbol
head :length_required # 411 Length Required head :ok # 200 OK
Using head with a status code
head 404 # 404 Not Found
Using counters with collections
When you’re rendering a collection partial, the partial_name_counter variable contains the position of the current element in the collection. For example:
<%= render(:partial => 'example', :collection => %w(rails-doc is cool)) %>
Now in _example.html.erb:
<p>Element: <%= example %> (index: <%= example_counter %>)</p>
It would produce:
<p>Element: rails-doc (index: 1)</p> <p>Element: is (index: 2)</p> <p>Element: cool (index: 3)</p>
As you can see, indexing starts from 1.
Link to same URL with different format
Use params.merge as options. Ex.
<%= link_to "RSS feed", params.merge(:format => :rss), :class => "feed_link" %>
Using a specific layout
To choose the layout (or no layout) for a method call the render method with a :layout option.
Add empty option and text is -select-
select :object, :method, options, :prompt => ‘-select-’
Getting textfield values into "link_to_remote" via Javascript Prototype
Use Prototype to get the value of a text field via Javascript, to pass to the ‘link_to_remote’ helper using code similar to below:
link_to_remote 'Link Name', {:update => "foo", :url => {:controller => "bar", :action => "baz"}, :with => "'model[textfield]=' + $F('textfield_id')"}
Connections to multiple databases
establish_connection can be used to connect to multiple databases. The immediate downside is that your rake migrations may not work properly without hacking.
In each model that resides in a different database we call:
establish_connection :different_database
You can check they are working by hitting script/console with:
>> App.connection.instance_eval {@config[:database]} => "app_development" >> AnotherDatabase.connection.instance_eval {@config[:database]} => "another_database"
Now doing a call to AnotherDatabase.find() will connect to the AnotherDatabase database and start returning results.
error in block code example
I guess there’s an error in this part of the code:
link_to_function("Show me more", nil, :id => "more_link") do |page| page[:details].visual_effect :toggle_blind page[:more_link].replace_html "Show me less" end
It doesn’t work. It should be:
link_to_function("Show me more", nil, :id => "more_link") do |page| page[:details].toggle "Blind" page[:more_link].replace_html "Show me less" end
Using Rails 2.1.0
Rails 2.1 caching internals
Rails 2.1 caching features are pretty much undocumented. Rob Anderton has documented some internal stuff here:
http://www.thewebfellas.com/blog/2008/6/9/rails-2-1-now-with-better-integrated-caching
benchmark and silence methods
benchmark (title, log_level = Logger::DEBUG, use_silence = true) {|| …}
Log and benchmark the workings of a single block and silence whatever logging that may have happened inside it (unless use_silence is set to false).
The benchmark is only recorded if the current level of the logger matches the log_level, which makes it easy to include benchmarking statements in production software that will remain inexpensive because the benchmark will only be conducted if the log level is low enough.
silence () {|| …}
Silences the logger for the duration of the block. To silence the logger in your controller, simply use:
NameOfController.logger.silence do
# your code here...
end
:case_sensitive is on by default?
In contrast to what the documentation said, :case_sensitive seems to be on by default. This is the case with MySQL at least, I’m not sure about other databases.
Better explanation for ActionController sweepers
The first sentence in this description is confusing. http://codelevy.com/articles/2008/03/04/rails-caching-sweepers-controllers-and-models explains it more clearly.
Use the :as option for SEO friendly URLs
The :as option to map.resources can be used to generate SEO friendly URLs like so:
Code Example
map.resources :operating_systems, :as => 'operating-systems' # operating_systems_path => /operating-systems
Turns hash keys into symbols
This method is part of ActiveSupport, which is a collection of classes and standard library extensions that are useful for Rails.
symbolize_keys! returns a new hash with all keys converted to symbols.
This can be helpful when you have a non-ActiveRecord model and you want your initialize method to take a hash of parameters. If you symbolize the hash, you can extract your parameters regardless of whether initialize received a hash of strings or hash of symbols.
Passing find() arguments
I you need to pass additional arguments to a scope (e.g. limit), do this:
Shirt.colored('red').all(:limit => 10)