Recent notes
RSS feedCan be used with has_many associations
You can also use this to validate that a has_many association has a specified number of records on the other end:
has_many :members validates_length_of :members, :minimum => 1
Complete Formatting Codes
%a - The abbreviated weekday name ("Sun")
%A - The full weekday name ("Sunday")
%b - The abbreviated month name ("Jan")
%B - The full month name ("January")
%c - The preferred local date and time representation
%C - Century (20 in 2009)
%d - Day of the month (01..31)
%D - Date (%m/%d/%y)
%e - Day of the month, blank-padded ( 1..31)
%F - Equivalent to %Y-%m-%d (the ISO 8601 date format)
%h - Equivalent to %b
%H - Hour of the day, 24-hour clock (00..23)
%I - Hour of the day, 12-hour clock (01..12)
%j - Day of the year (001..366)
%k - hour, 24-hour clock, blank-padded ( 0..23)
%l - hour, 12-hour clock, blank-padded ( 0..12)
%L - Millisecond of the second (000..999)
%m - Month of the year (01..12)
%M - Minute of the hour (00..59)
%n - Newline (\n)
%N - Fractional seconds digits, default is 9 digits (nanosecond)
- %3N millisecond (3 digits)
- %6N microsecond (6 digits)
- %9N nanosecond (9 digits)
%p - Meridian indicator ("AM" or "PM")
%P - Meridian indicator ("am" or "pm")
%r - time, 12-hour (same as %I:%M:%S %p)
%R - time, 24-hour (%H:%M)
%s - Number of seconds since 1970-01-01 00:00:00 UTC.
%S - Second of the minute (00..60)
%t - Tab character (\t)
%T - time, 24-hour (%H:%M:%S)
%u - Day of the week as a decimal, Monday being 1. (1..7)
%U - Week number of the current year, starting with the first Sunday as the first day of the first week (00..53)
%v - VMS date (%e-%b-%Y)
%V - Week number of year according to ISO 8601 (01..53)
%W - Week number of the current year, starting with the first Monday as the first day of the first week (00..53)
%w - Day of the week (Sunday is 0, 0..6)
%x - Preferred representation for the date alone, no time
%X - Preferred representation for the time alone, no date
%y - Year without a century (00..99)
%Y - Year with century
%z - Time zone as hour offset from UTC (e.g. +0900)
%Z - Time zone name
%% - Literal "%" character
t = Time.now #=> 2007-11-19 08:37:48 -0600 t.strftime("Printed on %m/%d/%Y") #=> "Printed on 11/19/2007" t.strftime("at %I:%M%p") #=> "at 08:37AM"
Complete Formatting Codes
NOTE: Some of these seem only to work for DateTime (e.g. %L, %N)
%a - The abbreviated weekday name ("Sun")
%A - The full weekday name ("Sunday")
%b - The abbreviated month name ("Jan")
%B - The full month name ("January")
%c - The preferred local date and time representation
%C - Century (20 in 2009)
%d - Day of the month (01..31)
%D - Date (%m/%d/%y)
%e - Day of the month, blank-padded ( 1..31)
%F - Equivalent to %Y-%m-%d (the ISO 8601 date format)
%h - Equivalent to %b
%H - Hour of the day, 24-hour clock (00..23)
%I - Hour of the day, 12-hour clock (01..12)
%j - Day of the year (001..366)
%k - hour, 24-hour clock, blank-padded ( 0..23)
%l - hour, 12-hour clock, blank-padded ( 0..12)
%L - Millisecond of the second (000..999)
%m - Month of the year (01..12)
%M - Minute of the hour (00..59)
%n - Newline (\n)
%N - Fractional seconds digits, default is 9 digits (nanosecond)
- %3N millisecond (3 digits)
- %6N microsecond (6 digits)
- %9N nanosecond (9 digits)
%p - Meridian indicator ("AM" or "PM")
%P - Meridian indicator ("am" or "pm")
%r - time, 12-hour (same as %I:%M:%S %p)
%R - time, 24-hour (%H:%M)
%s - Number of seconds since 1970-01-01 00:00:00 UTC.
%S - Second of the minute (00..60)
%t - Tab character (\t)
%T - time, 24-hour (%H:%M:%S)
%u - Day of the week as a decimal, Monday being 1. (1..7)
%U - Week number of the current year, starting with the first Sunday as the first day of the first week (00..53)
%v - VMS date (%e-%b-%Y)
%V - Week number of year according to ISO 8601 (01..53)
%W - Week number of the current year, starting with the first Monday as the first day of the first week (00..53)
%w - Day of the week (Sunday is 0, 0..6)
%x - Preferred representation for the date alone, no time
%X - Preferred representation for the time alone, no date
%y - Year without a century (00..99)
%Y - Year with century
%z - Time zone as hour offset from UTC (e.g. +0900)
%% - Literal "%" character
t = Time.now #=> 2007-11-19 08:37:48 -0600 t.strftime("Printed on %m/%d/%Y") #=> "Printed on 11/19/2007" t.strftime("at %I:%M%p") #=> "at 08:37AM"
Skips validations and callbacks
The method skips validations and callbacks. That is why it should be used with caution.
Code example
person.toggle :active
Use message param
The message param is invaluable in case test fails — if you use it to display relevant info, you will find out what went wrong much faster.
Reworking the silly example above:
assert some_list.include?(5)
will only tell you that
<false> is not true.
which isn’t terribly helpful, is it? But if you use message like that:
assert some_list.include?(5), "some_list = #{some_list.inspect}"
the output will be:
some_list = [1, 2]. <false> is not true.
which in most cases should give you strong hints as to why the test failed.
Available statuses
All the available statuses (extracted from SYMBOL_TO_STATUS_CODE hash) in a slightly more readable form:
:continue => 100 :switching_protocols => 101 :processing => 102 :ok => 200 :created => 201 :accepted => 202 :non_authoritative_information => 203 :no_content => 204 :reset_content => 205 :partial_content => 206 :multi_status => 207 :im_used => 226 :multiple_choices => 300 :moved_permanently => 301 :found => 302 :see_other => 303 :not_modified => 304 :use_proxy => 305 :temporary_redirect => 307 :bad_request => 400 :unauthorized => 401 :payment_required => 402 :forbidden => 403 :not_found => 404 :method_not_allowed => 405 :not_acceptable => 406 :proxy_authentication_required => 407 :request_timeout => 408 :conflict => 409 :gone => 410 :length_required => 411 :precondition_failed => 412 :request_entity_too_large => 413 :request_uri_too_long => 414 :unsupported_media_type => 415 :requested_range_not_satisfiable => 416 :expectation_failed => 417 :unprocessable_entity => 422 :locked => 423 :failed_dependency => 424 :upgrade_required => 426 :internal_server_error => 500 :not_implemented => 501 :bad_gateway => 502 :service_unavailable => 503 :gateway_timeout => 504 :http_version_not_supported => 505 :insufficient_storage => 507 :not_extended => 510
Good way to see what went wrong
Use the message parameter like that:
assert_response :success, @response.body
If this fails (the response isn’t a success), it will display the response body along with the failure message, thus allowing you to quickly find out what went wrong. If the response is e.g. 500, there will probably be some exception stacktrace displayed in the body. And so on.
Specify your own template
You can specify you own template this way:
def notice ... @template = "some_other_name.html.erb" end
Eagerness
Check out this simple example:
"Hello Ruby friend".sub(/^(.*)e/, 'X') # => "Xnd" "Hello Ruby friend".sub(/^(.*?)e/, 'X') # => "Xllo Ruby friend"
The question mark turns the dotstar into non-eager mode which means it will halt on the first subsequent "e" rather than the last one. This comes in handy e.g. for Cucumber step definitions.
Okay, but not really nice:
/^I am using rvm "([^\"]*)" with gemset "(.*)"$/
Much more readable and consistent equivalent to the above:
/^I am using rvm "(.*?)" with gemset "(.*?)"$/
AASM named scopes
If you are using the aasm plugin/gem, this will generate all named scopes for your various states.
Code example
Class Article < ActiveRecord::Base include AASM aasm_initial_state :created aasm_state :published aasm_state :unpublished aasm_state :deleted aasm_state :created aasm_event :publish do transitions :to => :published, :from => [:created] end aasm_event :unpublish do transitions :to => :unpublished, :from => [:created, :published] end aasm_event :delete do transitions :to => :deleted, :from => [:published, :unpublished] end aasm_states.each { |s| named_scope s, :conditions => { :state => s.to_s } } end
stub_chain is very useful when testing controller code
or any other chained method call type that you’d like to stub, example:
in your controller:
def new @user = current_site.users.new end
in your spec:
it "#new should assign a @user" do u = mock("User") controller.stub_chain(:current_site, :users, :new).and_return(u) assigns[:user].should == u end
whereas before you had to stub each chained method call separately:
it "#new should assign a @user" do u = mock("User") users = mock("Users collection", :new => u) site = mock("Site", :users => users) controller.stub!(:current_site).and_return(site) assigns[:user].should == u end
Please note that stub_chain was added to RSpec in version 1.2.6
Re: Caveat when using dynamic layouts
Since there’s no way to edit posts on here, I need to correct myself and say that what I posted before doesn’t work, since you can’t specify layout multiple times:
class OrdersController < BaseController layout :determine_layout, :only => :new layout "public", :except => :new # ... end
So don’t do that. The only way to ensure that the other actions get the default theme is to drop :only/:except and do the conditions yourself:
class OrdersController < BaseController layout :determine_layout private def determine_layout %w(new).include?(action_name) ? "some_layout" : "public" end end
All this to say, beware of :only/:except — they aren’t as useful as you think they are.
Deprecated in 1.9.x!
Use FileUtils::copy instead. It is also in 1.8.x, FileUtils, so call that one instead.
makedirs(path) to create file path
mkdir will only create a single directory on an existing path. If you want to create a full path, like the `mkdir -p /full/path` command, use the makedirs method.
1.8: File.makedirs(path) 1.9: FileUtils.makedirs(path)
Caveat when using dynamic layouts
Worth noting that if you have a controller which inherits from another controller which has a layout, and in this child controller you’re determining the layout at runtime using a method for specific actions, the other actions you are excluding will not inherit the layout from the parent controller.
For example, if you’ve got this
class BaseController < ApplicationController layout "public" end class OrdersController < BaseController layout :determine_layout, :only => :new # index, show, new, create, edit, update, destroy ... end
then OrdersController#index, #show, and #edit won’t get the "public" layout — in fact they won’t get a layout at all. So you’ll need to do this instead:
class OrdersController < BaseController layout :determine_layout, :only => :new layout "public", :except => :new # ... end
default_scope on create
If you specify :conditions in your default_scope in form of a Hash, they will also be applied as default values for newly created objects. Example:
class Article default_scope :conditions => {:published => true} end Article.new.published? # => true
However:
class Article default_scope :conditions => 'published = 1' end Article.new.published? # => false
configuration no longer in environment.rb
configure session store in config/initializers/session_store.rb
Saving other objects inside before_save
Don’t call .save or .update_attribute on other objects inside before_save callback.
Saving other objects inside of before_save callback results in flushing changed hash and the original object is not updated.
UPDATE observed sometimes, still investigating
Redirect...
See ActiveRecord::ConnectionAdapters::TableDefinition#column for details of the options you can use.
Possible gotcha
This method returns a Pathname object which handles paths starting with a / as absolute (starting from the root of the filesystem). Compare:
>> Rails.root => #<Pathname:/some/path/to/project> >> Rails.root + "file" => #<Pathname:/some/path/to/project/file> >> Rails.root + "/file" => #<Pathname:/file> >> Rails.root.join "file" => #<Pathname:/some/path/to/project/file> >> Rails.root.join "/file" => #<Pathname:/file>
See documentation for the class method
Since Rails version 2, this instance method no longer exists.
You may be looking for its namesake class method, ActiveRecord::Base.method_missing
Easy workaround for missing :through option
Note that belongs_to does not support :through option like has_many (although IMHO it would make sense in some cases), but you can easily simulate it with delegate.
For example:
class Person < ActiveRecord::Base belongs_to :team ... end class Task < ActiveRecord::Base belongs_to :person delegate :team, :to => :person end
There is of course more ways to do it, but this seems to be the easiest to me.
note: the example format regex is too lenient
The example regex for RFC 2822 email is too lenient. Sure it’s just an example, but it wound up in our code and we just had to fix it to match the RFC.
The regex as given allows any non-@ non-whitespace characters. But the RFC only allows these characters in mailbox names
alpha digit - ! \ # $ % & ' * + \ / = ? ^ _ ` { | } ~ ] +
and . is only allowed between atoms of 1 or more of the above.
Here’s the corrected regex:
:with => /\A([-a-z0-9!\#$%&'*+\/=?^_`{|}~]+\.)*[-a-z0-9!\#$%&'*+\/=?^_`{|}~]+@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i
Hash#except
Note that the ActiveSupport library provides the except and except! methods, which return the Hash minus the given keys. So you don’t need to write your own wrapper if you happen to be using Rails or ActiveSupport as a stand-alone library:
http://apidock.com/rails/ActiveSupport/CoreExtensions/Hash/Except/except
Re: POST DATA
The ampersand is more common, but the W3C recommends that all web servers support semicolon separators in the place of ampersand separators:
http://www.w3.org/TR/1999/REC-html401-19991224/appendix/notes.html#h-B.2.2
Extract the aggregated scoping options
If you want to get the aggregated scoping options of a chain of named scopes use ActiveRecord::Base.current_scoped_methods
It works in the fashion of:
Shirt.red.medium.alphabetical.current_scoped_methods # ==> { :create => {}, :find => { :conditions => {:color => 'red', :size => 'medium'}, :order => 'shirts.name ASC' } }
Check content_for content
There is a content_for? method in Rails wherewith you can check the content. http://github.com/rails/rails/commit/9cb8c812f2a23ab5653a7888740a014a02c97c18#diff-1
But it’s not in the last stable version (2.3.5) http://github.com/rails/rails/blob/v2.3.5/actionpack/lib/action_view/helpers/capture_helper.rb
re: Options
@ramanavel - The options are dependent on the cache store that you’re using. You’ll need to have a look at what the cache store you’re using allows.
e.g. MemCacheStore allows the use of time criteria based :expires_in, most of the cache stores don’t.
http://guides.rubyonrails.org/caching_with_rails.html might provide a little more information.
Using Unshift with Load Path's
Using unshift on your load path’s for Rails, Sinatra, etc, is a good way of ensuring that the file your including is going to be first.
Example
vendor = File.join(File.dirname(__FILE__), 'vendor') $LOAD_PATH.unshift File.expand_path(File.join(vendor, 'ultraviolet-0.10.5', 'lib'))

