Notes posted by szeryf

RSS feed
November 16, 2011
0 thanks

Examples in a readable format :)

Here are the above examples in a somewhat more readable format:

# Assert a basic route: a controller with the default action (index) 
assert_routing/home’, :controller =>home’, :action =>index’
# Test a route generated with a specific controller, action, and parameter (id) 
assert_routing/entries/show/23’, :controller =>entries’, :action =>show’, :id => 23
# Assert a basic route (controller + default action), with an error message if it fails 
assert_routing/store’, 
               { :controller =>store’, :action =>index’ }, 
               {}, 
               {},Route for store index not generated properly’
# Tests a route, providing a defaults hash 
assert_routingcontroller/action/9’, 
               {:id =>9”, :item =>square”}, 
               {:controller =>controller”, :action =>action”}, 
               {}, 
               {:item =>square”}
# Tests a route with a HTTP method 
assert_routing({ :method =>put’, :path =>/product/321’ }, 
               { :controller =>product”, :action =>update”, :id =>321” })
October 8, 2011
6 thanks

Undocumented :location option

You can use undocumented :location option to override where respond_to sends if resource is valid, e.g. to redirect to products index page instead of a specific product’s page, use:

respond_with(@product, :location => products_url)  
April 22, 2010
2 thanks

Dynamic exists? methods

There are no dynamic exists? methods analogous to dynamic finders, which means that while you can do this:

Person.find_by_name('David')

you can’t do this:

Person.exists_by_name('David') # DOES NOT WORK

nor this:

Person.exists_by_name?('David') # DOES NOT WORK

However, you can simulate this with dynamic scope:

Person.scoped_by_name('David').exists?

You’ll have to admit that this is so much better than the plain old method:

Person.exists?(:name => "David")
April 20, 2010
2 thanks

Does not work with polymorphic relations

If you have polymorphic relations, e.g.:

class Bookmark < ActiveRecord::Base
  belongs_to :thing, :polymorphic => true
  belongs_to :owner, :polymorphic => true
end

and you want to ensure that a thing can bookmarked by an owner at most once, you can’t do this:

validates_uniqueness_of :thing, :scope => :owner

Instead, you must use the real column names, e.g.:

validates_uniqueness_of :thing_id, :scope => [:thing_type, :owner_id, :owner_type]
March 29, 2010
0 thanks

Wrong example

In the authentication filter example above, the time condition should be reversed: we only want to find the user if time is still in the future (because it’s the valid-until time).

So the example should look like this:

id, time = @verifier.verify(cookies[:remember_me])
if time > Time.now
  self.current_user = User.find(id)
end
March 11, 2010
0 thanks

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.

March 11, 2010
3 thanks

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
March 11, 2010
2 thanks

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.

February 25, 2010
2 thanks

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>
February 23, 2010
3 thanks

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.

January 18, 2010
1 thank

Undeprecated version

The undeprecated version of this function is here: ActionView::Helpers::PrototypeHelper#link_to_remote

December 31, 2009
2 thanks

Replacing with "\" and match — a simple solution

A somewhat different approach to the same problem:

v.gsub(/(?=\W)/, '\\') #=> Foo\ Bar\!

But from what you are trying to achieve I suspect you might be interested in Regexp.escape method :)

December 28, 2009
4 thanks

Attribute names are Strings, not Symbols

Another possible gotcha – the returned hash keys are of type String, not Symbol:

user.attributes["login"] # => "joe"
user.attributes[:login] # => nil
November 5, 2009 - (>= v2.1.0)
7 thanks

Named scope better than conditions

In modern versions of Rails, in most cases a named_scope is a better alternative to using :conditions on your has_many relations. Compare:

class User
  has_many :published_posts, :conditions => {:published => true}
end
user.published_posts

with:

class Post
  named_scope :published, :conditions => {:published => true}
end
class User
  has_many :posts
end
user.posts.published

It’s better because the Post’s logic (“am I published?”) should not be coupled within User class. This makes it easier to refactor: e.g. if you wanted to refactor the boolean :published field into a :status field with more available values, you would not have to modify User class. Having to modify User when you refactor some implementation detail of Post class is clearly a code smell.

This also applies to :order, :group, :having and similar options.

October 30, 2009
0 thanks

Outputs name even if condition is false

Please note that if the condition is false, link_to_if will still output the name given as a plain text (as documented above). If you want nothing printed at all, you’ll have to stay with the old and trusty:

link_to "Login", ... if @current_user.nil?
October 30, 2009
2 thanks

Outputs name even if condition is false

Please note that if the condition is false, link_to_if will still output the name given as a plain text (as documented above). If you want nothing printed at all, you’ll have to stay with the old and trusty:

link_to "Login", ... if @current_user.nil?
October 15, 2009
2 thanks
August 18, 2009
3 thanks

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();"
August 11, 2009
2 thanks

Common signals

Some of the more commonly used signals:

1       HUP (hang up)
2       INT (interrupt)
3       QUIT (quit)
6       ABRT (abort)
9       KILL (non-catchable, non-ignorable kill)
14      ALRM (alarm clock)
15      TERM (software termination signal)
August 7, 2009
0 thanks
August 7, 2009
2 thanks

Most common use case

Most common use case is probably:

Rails.cache.fetch "some key" do
  compute some value
end

This computes some value and caches it. Subsequent invocations will return cached value (as long as it is still cached).

August 7, 2009
3 thanks

Documentation

This method only returns a cache manager object of sorts, to see what you can do with it, see ActiveSupport::Cache::Store.

July 24, 2009
1 thank

Instance method

Please note that this is an instance method, not a class method (which seemed more logical for me and took me a while to see what’s wrong). So, you call it like this:

User.new.from_json '{"id": 1, "name": "DHH"}' # RIGHT!

not like this:

User.from_json '{"id": 1, "name": "DHH"}' # WRONG!
July 16, 2009
0 thanks

Usage example

Usage example:

cube = lambda {|x| x * x * x } 
cube.call(3)  # => 27
cube.call(6)  # => 216
July 14, 2009
2 thanks

Not for floats

You should use assert_in_delta when comparing floating-point numbers.

July 13, 2009
1 thank

Any base logarithm

Using basic arithmetic you can get logarithm with any base:

def log_with_base base, num
  Math.log(num) / Math.log(base)
end

Examples:

>> log_with_base 2, 10
=> 3.32192809488736
>> log_with_base 2, 2
=> 1.0
>> log_with_base 2, 4
=> 2.0
>> log_with_base 2, 16
=> 4.0
>> log_with_base 4, 16
=> 2.0
July 13, 2009
0 thanks

Any base logarithm

Using basic arithmetic you can get logarithm with any base:

def log_with_base base, num
  Math.log(num) / Math.log(base)
end

Examples:

>> log_with_base 2, 10
=> 3.32192809488736
>> log_with_base 2, 2
=> 1.0
>> log_with_base 2, 4
=> 2.0
>> log_with_base 2, 16
=> 4.0
>> log_with_base 4, 16
=> 2.0
June 25, 2009
2 thanks

Antonym of empty?

The antonym of empty? is Enumerable#any? method:

[].empty?  #=> true
[].any?    #=> false
[1].empty? #=> false
[1].any?   #=> true

Be cautious however, if your array might contain nil’s or false’s:

[false, nil].any? #=> false
June 18, 2009
3 thanks

Expensive method!

This method builds the a new hash every time it’s called, so be cautious not to use it in loops etc.

May 31, 2009
2 thanks

You can call several times

You can call it several times, like:

class Comment < ActiveRecord::Base
  validate :must_be_friends
  validate :must_be_awesome
  ...

or with several arguments:

class Comment < ActiveRecord::Base
  validate :must_be_friends, :must_be_awesome
  ...