The note is not new, but I am sure that even now not everyone knows all of the following (Hereinafter, the italics of the translator).When I look at my own, and even on someone else's, code on the rails, I often see unrealized possibilities for applying certain rail techniques. I would like to list some tricks and tips for improving the efficiency of the application and the code, as a reminder for myself and for you.
Measuring speed in controllers is very simple. Use the benchmark method in any model.
User.benchmark ("adding and deleting 1000 users") do
1000.times do
User.create (: name => 'something')
x = User.find_by_name ('something')
x.destroy
end
end
Your code, of course, will be better ;-) Normal SQL logs will not be written inside the benchmark method, only the results.
')
acts_as_nested_set - almost everyone
(ho-ho) is well acquainted with acts_as_tree, but
acts_as_nested_set appeared imperceptibly in the rails. This is similar to acts_as_tree, but with conveniences: you can select all the children (and their heirs) of the same node with one for free. There is a
list of methods .
Simple collections via to_proc - tired of writing
post.collect { |p| p.title }
post.collect { |p| p.title }
or
post.select { |p| p.activated? }.collect{ |p| p.title}
post.select { |p| p.activated? }.collect{ |p| p.title}
post.select { |p| p.activated? }.collect{ |p| p.title}
? With the help of a small hack we translate characters into procedures. You can write
post.collect(&:title)
or
post.select(&:activated?).collect(&:title)
!
Here it is much more .
Transformation of arrays into sentences - if you need to display a list of names in the display, you take an array of the type
['Peter', 'Fred', 'Chris']
, combine them with commas and add “and” before the last one, which could be a bit annoying. The method
to_sentence
to the rescue:
names.to_sentence
returns
"Peter, Fred, and Chris"
.
(Yes, it is not portable and Anglo-centric. In the notes to the original article about this more.)Sending a file to the user - usually static files are transferred via a direct URL bypassing the rail application. Nevertheless, in some situations it may be useful to hide the location of the file, especially if you are sending something valuable, like an e-book. It may also be necessary to restrict sending files to only logged in users. The problem is solved by
send_file
. Files are transmitted over 4096 bytes, so even large files will not slow down the system.
Selecting page elements via RJS - changing an element in RJS is easy, but what if we don’t know which element needs to be changed and would like to be addressed via a CSS request? This is possible with the select method. For example,
page.select('#items li').each { |item| item.hide }
page.select('#items li').each { |item| item.hide }
. Powerful stuff!
Existence check - when executing Model.find (id), we will get an exception if the “id” element was not found. To avoid this, we first run Model.exists? (Id) to see if there is one.
Numeric helpers for frequent tasks — they are rarely used, but are nevertheless very useful:
number_to_currency(1234567.948) # => $1,234,567.95
or
human_size(1234567890) # => 1.1GB
or
number_with_delimiter(999999999) # => 999,999,999
. There are others.
(The same remark regarding localization.)Simple testing of routing - test_routing - helper, which replaces the default "routes" in routes.rb for experiments. For example:
with_routing do | set |
set.draw {set.connect ': controller /: id /: action'}
assert_equal (
['/ content / 10 / show', {}],
set.generate (: controller => 'content',: id => 10,: action => 'show')
)
end
Here more .
A lot of interesting about the request -
request.post?
and
request.xhr?
- Popular ways to look at POST-and Ajax requests, but there are other, not so well-known. For example,
request.subdomains
will return an array of subdomains that can be used for authorization,
request.request_uri
will give the full local URI,
request.host
is the full host name,
request.method
will return a lower case method, and
request.ssl?
will determine if it is SSL.
Further performance improvements - by default, rails record sessions to the local file system. Many change it to ActiveRecordStore to record sessions into the database. Memcached will be an even faster alternative, but it is not so easy to install (and it will not work if the servers are foreign, etc.). Nevertheless, it can be done faster than ActiveRecordStore, through the use of
Stefan Kaes’s SQLSessionStore . The plugin bypasses the drawbacks of ActiveRecordStore through its SQL session saving technique.
Caching static content at startup - if you have data that does not change from restart to restart, cache it. For example, it could be a YAML or XML file in / config-e with application settings, and it can be loaded into a constant in environment.rb, speeding up and simplifying access.
Checking the validity of (X) HTML is not for everyone, but if your output is valid, then there are chances that your impressions
(view) are rendered correctly. Scott Raymond developed the
helper assert_valid_markup , which can be used for functional testing.
More neat testing of the HTML output - we merge the Hpricot parser from wai (
why ) with a special test extension, and get powerful tests like
assert_equal "My title", tag('title')
or
assert element('body').should_contain('something')
. This is perfect for testing custom templates. Anyway, better than
assert_tag
!
Running long processes separately in the background - there is a small
BackgrounDRb
framework from Ezra Zygmuntovich (
Ezra Zygmuntovich ), which runs as a daemon and accepts tasks from the rail application, and executes them independently. A powerful thing that helps in sending letters, receiving URLs, and other things that can slow down the execution time of the request of the main application. The demo task increases the variable by 1, and then makes
sleep
for 1 second. Next, we do the rail method that polls this variable, and we feel the difference.
Here is more .
Beautiful IDs in URLs - replace
to_param
in your model and return something like
"#{id}-#{title.gsub(/[^a-z0-9]+/i, '-')}"
, for URL kind of
yoursite.com/posts/show/123-post-title-goes-here...
yoursite.com/posts/show/123-post-title-goes-here...
It’s much more pleasant for the user, and you don’t need to change anything in
Post.find(params[:id])
, since non-digital characters will be thrown automagically.
Full explanation here . (link is broken, it seems)
Selecting pieces of functionality in engina - everyone has heard about plug-ins, but unfortunately few people use engina! Engines are plugins on steroids (
or barbiturates ). They can have their own models, controllers and displays, and they can integrate with any application. This allows you to select common pieces of functionality (logins, user management, content management, etc.) into separate “engines” that can be included in different projects in a matter of minutes. Say no to writing stupid logins! Engines are cool, but they should be much cooler too.
Calculations - do you want to calculate the maximum, minimum, average, amount for the data in the table? This is possible with
Calcuations from
ActiveRecord
.
Person.average('age'), Person.maximum(:age, :group => 'last_name'), Order.sum('total')
: all this is now embodied. Most of this can be configured with additional options, read if you do not already have it in the code.
Data output to XML or YAML is not only to create a .rxml Builder template for output to XML.
ActiveRecord
has a method
to_xml
, which
to_xml
result in XML. It works with both simple objects and whole tables:
User.find(:all).to_xml
. Inclusions are also supported:
Post.find(:all, :include => [:comments]).to_xml
. The same in YAML, using
to_yaml
.