Recent notes
RSS feedupdate_attribute!
I don’t know why, but method update_attribute! is missing. May be it would be useful for somebody:
class ActiveRecord::Base def update_attribute!(name, value) send(name.to_s + '=', value) save! end end
:conditions examples
:conditions => {:login => login, :password => password}
:conditions => [‘subject LIKE :foo OR body LIKE :foo’, {:foo => ‘woah’}]
(from the book “The Rails Way”)
Migration helpers
You can add your own migration helpers as references:
Code example
class ActiveRecord::ConnectionsAdapters::TableDefinition def counter_caches(*args) args.each { |col| column("#{col}_count", :integer, :default => 0) } end end class CreateUsers < ActiveRecord::Migration def self.up create_table :users do |t| t.string :first_name, :last_name, :email t.counter_caches :photos, :messages t.timestamps end end def self.down drop_table :users end end
select_tag with options_for_select example
An example of using options_for_select with select_tag
select_tag 'user_id', options_for_select(@users.collect{ |u| [u.name, u.id] })
This would generate something like:
<select id="user_id" name="user_id"> <option value="1">Brad</option> <option value="2">Angie</option> <option value="3">Jenny</option> </select>
Nested resources in form_for
If you like doing things RESTfully and have a model relationship like:
Post_ has many Comments_
Then you can construct a form_for within your view to mirror this relationship when creating comments:
form_for [@post, @comment] do |f| ... end
You also need to make sure your routes reflect this relationship:
map.resources :post, :has_many => [:comments]
Demo: 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.
reverse_merge(other_hash)
Performs the opposite of merge, with the keys and values from the first hash taking precedence over the second.
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.
Mapping Order
Something I always forget is the order in which each mapping should be specified.
The first item is the attribute name in the ActiveRecord model, and the second is the name of the attribute in the ValueObject (the writer uses it to read from the VO).
Furthermore, the order in which mapping pairs are specified should be the same as the order the attributes are specified in the ValueObject’s initialize method (for the reader to be able to instantiate a VO with the record’s values).
nachokb
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
migration example
def self.up create_table :regs do |t|
t.column :login, :string, :limit=>'10' t.column :pass, :string, :limit=>'10' t.column :email, :string, :limit=>'20' t.column :fio, :string, :limit=>'30' t.column :born, :date t.column :phone_code, :integer, :limit=>'3' t.column :phone_post, :integer, :limit=>'7' t.column :password, :string, :limit=>'20' t.column :pass_when, :date t.column :pass_who, :string,:limit=>'30' t.column :wmid, :integer, :limit=>12 t.column :wmr, :integer, :limit=>12 t.column :wmz, :integer, :limit=>12 end
add_index :regs, [:login, :wmr, :wmz], :unique => true end
watch out for urls with &
image_tag(‘x.com/aaa?a=1&b=2’) = x.com/aaa?a=1&b=2
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.
around_filter code example
This is how it’s used:
around_filter do |controller, action| do_your(:stuff) do action.call end end