Recent notes
RSS feedAnchor tag in link_to
Code example
link_to("some text", articles_path(:anchor => "comment"))
will output <a href = “/articles#comment” >some text
Date_select with assert_valid_keys
If you are using date_select with assert_valid_keys you have to allow 3 parameters named field(1i), field(2i) and field(3i).
For example with field
date_select("post", "written_on")
You have to allow following fields:
params[:post].assert_valid_keys( 'written_on(1i)', 'written_on(2i)', 'written_on(3i)' )
Usage examples
Basic usage:
User.should_receive(:find).with(:all, anything).and_return("hello world")
Now:
User.find(:all, :conditions => "foo") #=> "hello world"
But you can also use blocks for more complex matching logic. For example:
User.should_receive(:find) { |*args| if args.size == 2 "received two arguments" else "something else" end }.at_least(:once)
Now:
User.find(:all, :conditions => "bar") #=> "received two arguments" User.find(5) #=> "something else"
Of course normally you’d return mocks instead of strings.
If you want to avoid SQL...
…you’re probably looking for http://apidock.com/rails/ActiveRecord/Calculations/ClassMethods/count
Empty elements
If you want to output an empty element (self-closed) like “br”, “img” or “input”, use the tag method instead.
Remember to sanitize name
While useful when in need of richer markup inside a link, the name parameter isn’t sanitized or escaped and thus should be escaped when its content can’t be guaranteed to be safe.
E.g.
link_to(url, url)
may cause problems with character entities if url contains ampersands.
Correct usage
link_to(h(url), url)
This applies to all dynamic content.
See column
See the end part of the docs on column for example uses.
Capping values
This method is very useful when you want to cap values:
# minimum ≤ value value = [input.to_i, minimum].max # value ≤ maximum value = [input.to_i, maximum].min # minimum ≤ value ≤ maximum value = [ [input.to_i, minimum].max, maximum ].min # Practical example: Make sure destination is within container destination.x = [ [current.x + current.velocity.x, 0].max, container.width ].min destination.y = [ [current.y + current.velocity.y, 0].max, container.height ].min
Usage example
Some examples:
# Remove even numbers (1..30).reject { |n| n % 2 == 0 } # => [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29] # Remove years dividable with 4 (this is *not* the full leap years rule) (1950..2000).reject { |y| y % 4 != 0 } # => [1952, 1956, 1960, 1964, 1968, 1972, 1976, 1980, 1984, 1988, 1992, 1996, 2000] # Remove users with karma below arithmetic mean total = users.inject(0) { |total, user| total += user.karma } mean = total / users.size good_users = users.reject { |u| u.karma < mean }
Reverse of this
If you want to do the reverse of this, e.g. go from a specific date and back to a certain day of the previous week, you can implement it like this:
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
If you do not want to make your own method of this, but just want to do it in a regular chaining of date methods (like Date.today.next_year.at_midnight), you can do it like the following:
(date - 7).next_week(:tuesday) # Tuesday, last week
Please note that you just need to subtract 7 if you want to move back a week. Only use these methods if you want to go to a specific day of the week.
Reverse naming
The reverse of this is last_month and not previous_month, like one might believe from the naming.
Reverse naming
The reverse of this is last_year and not previous_year, like one might believe from the naming.
use #collect instead of #each
The earlier reminder to use #collect instead of #each applies regardless of whether the tag is nested or not.
This is counterintuitive, as #collect returns an array of strings of HTML tags, but ActionView renders it properly.
Clear and simple rescue
noxyu3m, your code is rescuing all exceptions, not just ActiveRecord::RecordInvalid.
I think this syntax is a bit more clear than using the global variable.
def create @model = Model.new(params[:model) @model.save! rescue => err # rescues all exceptions logger.error(err.to_s) end
Simple rescue
Take it easy:
def create @model = Model.new(params[:model) @model.save! rescue logger.error(!$.to_s) end
Global variable !$ refers to the Exception object.
throws exception
when use use Model.find([1,2,3,4])
throws exception if no record exists with any of this ID
New test syntax
You can use either one and even mix in the same test case if you want:
class Test < Test::Unit::TestCase # old way to define a test method (prefix with test_) def test_should_be_valid_without_content assert Comment.new.valid? end # new way to define a test test "should be valid without content" do assert Comment.new.valid? end end
Real life use
If you’re wondering what the base64 format is used for, here are some examples:
-
HTTP Basic authentication: encode your username and password as one string, and add it as a header of an HTTP request. When a page requiring basic authentication gets called from a browser it results in a generic Username/Password dialog from that browser. See also http://en.wikipedia.org/wiki/Basic_access_authentication
-
Encode the binary content of images to base64 and embed it in XML documents, for example in web services
-
For more information see http://en.wikipedia.org/wiki/Base64
Just note that the encoded (character) data is about 30% larger than un-encoded (binary) data.
using collection=objects
It will fire one insert query per new record
Binary files
Another real important flag is b when dealing with binary files. For example to download an mp3 from the internet you need to pass the b flag or the data will be screwed up:
# Downloads a binary file from the internet require 'open-uri' url = "http://fubar/song.mp3" open(url, 'rb') do |mp3| File.open("local.mp3", 'wb') do |file| file.write(mp3.read) end end
Don’t say you haven’t been warned. :)
Other regular-expression modifiers
Likewise you can set Regexp::IGNORECASE directly on the regexp with the literal syntax:
/first/i # This will match "first", "First" and even "fiRSt"
Even more modifiers
-
o – Perform #{} interpolations only once, the first time the regexp literal is evaluated.
-
x – Ignores whitespace and allows comments in * regular expressions
-
u, e, s, n – Interpret the regexp as Unicode (UTF-8), EUC, SJIS, or ASCII. If none of these modifiers is specified, the regular expression is assumed to use the source encoding.
Literal to the rescue
Like string literals delimited with %Q, Ruby allows you to begin your regular expressions with %r followed by a delimiter of your choice.
This is useful when the pattern you are describing contains a lot of forward slash characters that you don’t want to escape:
%Q(http://) # This will match "http://"
Literal syntax
As you propably know you can create an Array either with the constructor or the literal syntax:
Array.new == [] # => true
But there is also another nice and concise literal syntax for creating Arrays of Strings:
["one", "two", "three"] == %w[one two three] # => true
You can use any kind of parenthesis you like after the %w, either (), [] or {}. I prefer the square brackets because it looks more like an array.
Use this!
You should raise your own ArgumentError in methods to notify users of your class, if you think certain kinds of arguments aren’t acceptable.
def transfer_money(amount) unless amount.is_a?(Number) raise ArgumentError.new("Only numbers are allowed") end # ... Do the actual work end
Useful scenario
This can be quite useful, for example when writing a command line script which takes a number of options.
Example
Let’s say you want to make a script that can make the basic CRUD operations. So want to be able to call it like this from the command line:
> my_script create > my_script delete
The following script allows you to use any abbreviated command as long as it is unambiguous.
# my_script.rb require 'abbrev' command = ARGV.first actions = %w[create read update delete] mappings = Abbrev::abbrev(actions) puts mappings[command]
That means you can call it like this:
> my_script cr > my_script d
And it will print:
create delete
Security issue with non-HTML formats
Please note that using default to_xml or to_json methods can lead to security holes, as these method expose all attributes of your model by default, including salt, crypted_password, permissions, status or whatever you might have.
You might want to override these methods in your models, e.g.:
def to_xml super( :only => [ :login, :first_name, :last_name ] ) end
Or consider not using responds_to at all, if you only want to provide HTML.
Cheat Sheet
I have written a short introduction and a colorful cheat sheet for Perl Compatible Regular Expressions (PCRE) as used by Ruby’s Regexp class:
http://www.bitcetera.com/en/techblog/2008/04/01/regex-in-a-nutshell/
Cheat Sheet
I have written a short introduction and a colorful cheat sheet for Perl Compatible Regular Expressions (PCRE) as used by Ruby’s Regexp class:
http://www.bitcetera.com/en/techblog/2008/04/01/regex-in-a-nutshell/
Cheat Sheet
I have written a short introduction and a colorful cheat sheet for Perl Compatible Regular Expressions (PCRE) as used by Ruby’s Regexp class:
http://www.bitcetera.com/en/techblog/2008/04/01/regex-in-a-nutshell/
Easier way
See http://apidock.com/rails/ActionController/TestProcess/fixture_file_upload for easier way to test file uploads.