MySQL: Do not use "WHERE id IN (SELECT ....)"
Note: This applies specifically to MySQL. In PostgreSQL for example, this is not an issue.
If you care about performance, never use a query like
UPDATE users SET has_message = 1 WHERE users.id IN (SELECT user_id FROM messages)
MySQL does not optimize this and seems to scan the temporary table, which isn't indexed, for every row in the update statement. This applies to other statements than UPDATE as well.
Instead, either use a JOIN like
UPDATE users INNER JOIN messages ON messages.user_id = users.id SET has_message =...
How the Clearance gem remembers and clears sessions
Clearance is a gem that provides authentication functionality (e.g. login, logout). This note explains, how the clearance login, logout and (in old Clearances) remember me functionality works.
Login
Clearance defines a database column called "remember_token". When you login in, that token will be saved in a cookie. For that reason you don't have to re-sign-in when you close and open the browser again.
This also means that you can be logged in in more than a single browser. Also see [When ses...
How to use html_safe correctly
By default, Rails views escape HTML in any strings you insert. If you want to insert HTML verbatim, you need to call #html_safe. However, #html_safe does not "unescape" a string. It merely marks a string as safe for unescaped insertion.
How html_safe works
Calling html_safe on a String returns a new object that looks and acts like a String, but actually is a ActiveSupport::SafeBuffer:
"foo".length
# => 3
"foo".class
# => String
"foo".html_safe.length
# => 3
"foo".html_safe.class
# => ActiveSupport::S...
Cucumber.yml was found, but could not be parsed.
If you encounter the error message above when running cucumber, just execute...
rm rerun.txt
...in the Rails directory.
Or run...
tests
...from the geordi gem. This will do the work for you automatically.
Ruby 2.0 Implementation Work Begins: What is Ruby 2.0 and What’s New?
While 2.0 will include a number of syntax changes, new features and general improvements, mentioned below, it is anticipated to remain backward compatible with code written for 1.9.3 and Matz has stated that the changes are less significant than those made in the 1.8 to 1.9 jump.
Javascript equivalent of Ruby's array.collect(&:method)
The most common use case for Ruby's #collect is to call a method on each list element and collect the return values in a new array:
['hello', 'world', 'this', 'is', 'nice'].collect(&:length)
# => [5, 5, 4, 2, 4]
Although there is no equivalent to this idiom in naked Javascript, there is a way to collect object properties (but not method results) if you are using common Javascript libraries.
If you are using jQuery with the Underscore.js utility library, you can use [pluck](htt...
Monitor a Rake task with God
In order to monitor a Rake task using God your Rake file must write a file with its process ID (PID) to a path determined by God. This way God can check whether the Rake process is still alive.
Here is how to do this: In your God config, call the Rake task with an environment variable PIDFILE. This variable should equal the PID file path desired by God:
God.watch do |w|
w.dir = "#{rails_root}"
w.name = "my_task"
w.interval = 10.seconds
w.pid_file = "#{rails_root}/tmp/pids/#{w.name}...
Mailcatcher: An alternative to inaction_mailer
Looks simpler than inaction_mailer:
gem install mailcatcher
mailcatcher
Setup Rails to send mails to 127.0.0.1:1025. Usually you want the following config in config/environments/development.rb and maybe in test.rb or cucumber.rb.
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
:address => 'localhost',
:port => 1025
}
Now you can see sent mails in your browser when opening http://127.0.0.1:1080
Note: In order to s...
Start Rails console or server with debugger
When you require the Ruby debugger to be available from your Rails console (e.g. you want to inspect a method's magic), you need to enable it explicitly:
script/console --debugger
If you cannot access local variables etc, see this card.
WEBrick
For WEBrick, enable it similarly:
script/server --debugger
Properly adding fields with default values to a model
When adding a new field to your model's database table, don't set any defaults in the database.
It makes people wonder why they get such values when reading attributes.\
Why? Because nobody looks at the database layout since such things are part of your application's logic -- and thus they belong into the corresponding model.
How to
Do it like this:
-
In your migration, after adding the field, update all fields to your desired default:
update "UPDATE users SET locked = #{quoted_false};" -
In your model, set a defau...
Install the Oniguruma gem
Oniguruma is an advanced regular expression engine for Ruby.
Install Oniguruma with binary dependencies like this:
sudo apt-get install libonig2 libonig-dev
sudo gem install oniguruma
On the Mac do:
brew install oniguruma
sudo gem install oniguruma
MySQL: For each group, retrieve a comma-separated list of values in a given column
The technique described in this card has an important caveat: The result of GROUP_CONCAT is truncated to the maximum length that is given by the group_concat_max_len system variable, which has a default value of 1024. This will cause horrible, data-destroying bugs in production. For this reason you should probably not use GROUP_CONCAT ever. At least you must set the value of group_concat_max_len to an insanely high value on every database server your application runs on.
Lik...
Using heredoc for prettier Ruby code
You can use heredoc to avoid endlessly long lines of code that nobody can read. Heredoc strings preserve linebreaks and can be used like this:
def long_message
puts(<<-EOT)
Here goes a very long message...
Sincerely,
foobear
EOT
end
<<-EOT will be somewhat of a placeholder: anything you write in the line after you used it will be its value until you write EOT in a single line.
You can use any string to flag your heredocs. To be more verbose you...
How to fix: Gems are unavailable although they are installed
- If Rails or Rake are complaining about a missing gem that is listed in your
Gemfile.lockand the listed version is properly installed, something is seriously wrong and needs to be fixed. - If you accidently executed
bundle install some_gemalthough you wantedbundle update some_gem
What is wrong
Let's say your Gemfile asks for some-gem which you can see when running gem list but bundle show some-gem just gives you an error:
Could not find gem 'some-gem', in any of the sources
Another indicator: Doing a `...
Use a Ruby method like a block or lambda
Sometimes you want to use a vanilla Ruby method like a block. You can use Object#method to obtain a method reference that responds to #call:
foo_plus = "foo".method(:+)
foo_plus.call("bar") # => "foobar"
The method reference also understands #to_proc so you can feed it to block-taking methods by prefixing it with &:
printer = method(:puts)
[1, 2, 3].each(&printer) # will print one line per number
Selenium WebDriver 2.5.0, 2.6.0 fails when selecting options from select boxes
We are consistently having trouble with selenium-webdriver > 2.5.0 where whenever we try to select an option from a <select> Capybara complains:
No such option 'Foo' in this select box. Available options: 'Foo', 'Bar', 'Baz' (Capybara::OptionNotFound)
This seems to happen with both old and new versions of Firefox. Our workaround so far is to freeze the gem at version 0.2.2.
sstephenson/execjs - GitHub
ExecJS lets you run JavaScript code from Ruby. It automatically picks the best runtime available to evaluate your JavaScript program, then returns the result to you as a Ruby object.
Auto-generate state_machine graphs as PNG images
The state_machine gem comes with a rake task that lets you generate PNG graphs from any model using state_machine.
Install the required dependencies like this:
sudo apt-get install graphviz
sudo gem install ruby-graphviz
You can now generate a graph like this:
rake state_machine:draw CLASS=ModelUsingStateMachine
Replace ModelUsingStateMachine with the name of your model class.
If it the raketask does not exist for you, add to Rakefile (in your pr...
Defining custom errors in Ruby
class Errormaster
CoffeeIsOut = Class.new(StandardError)
# is prettier than
class CoffeeIsOut < StandardError; end
end
Reference such an error class with Errormaster::CoffeeIsOut.
How to install a frozen version of Firefox for your Selenium tests
Whenever Firefox updates, all your Cucumber features that use Selenium break. This is annoying.
In order to remedy this, version 0.5.0 of our geordi gem comes with a script that helps you create an unchanging version of Firefox for your Selenium tests. In particular, this new copy of Firefox will have the following properties:
- It won't update itself with a newer version
- It can co-exist with your regular Firefox installation (which you can update at will)
- It will use a profile separate from the one...
mojombo/grit - GitHub
Grit gives you object oriented read/write access to Git repositories via Ruby.
Rails 3.1.0 has been released!
jQuery as new default Javascript library, streaming response support, attr_accessible with roles, prepared statements, easier migrations.
Ruby: Convert a time string to your local time zone
If you have a time given in a different time zone than your local one, parsing will convert it for you:
>> Time.parse('September 2nd, 3pm PST')
=> 2011-09-03 01:00:00 +0200
Note that in pure Ruby you need to require "tzinfo" (Ruby 1.9) or require "time" (Ruby 1.8) for Time.parse to be available.
Fix: "undefined method `bytesize' for #<Array>"
I believe that when WEBrick has trouble bringing up your Rails application, the WEBrick component that is supposed to print you a pretty error message has a bug and sometimes fails with this message:
"undefined method `bytesize' for #<Array>"
Starting the application in Passenger gave me a stacktrace in log/development.log that pointed to the actual problem.
Possible causes discovered by looking at the logs
-----------------------------------------------------...