Upgrading Cucumber and Capybara to the latest versions available for Rails 2
Specify these gem versions in your Gemfile:
gem 'cucumber', '~> 1.3.0'
gem 'cucumber-rails', '= 0.3.2' # max version for Rails 2
gem 'capybara', '< 2' # capybara 2+ requires Rails 3
gem 'mime-types', '< 2' # dependeny of capybara
gem 'nokogiri', '< 1.6' # dependency of capybara
gem 'rubyzip', '< 1' # dependency of selenium-webdriver, rubyzip 1+ requires Ruby 1.9
gem 'cucumber_factory'
gem 'database_cleaner', '< 1'
gem 'cucumber_spinner', '~> 0.2.5'
gem 'launchy', '~> 2.1.2'
With these versions set, `...
Onload callback for dynamically loaded images
Sometimes you need to dynamically load an image and do something as soon as its loaded (when for example its size is already available).
With jQuery, this seems to work across browsers:
$('<img>')
.attr('src', '')
.load(function() {
alert('fully loaded!');
})
.attr('src', '/the/real/image/url');
Customize your Bash prompt
The shell variable PS1 holds your bash prompt. You might want to change it to serve your needs best. Here is how to:
General
- non-printing escape sequences in your prompt have to be inclosed in
\[\e[and\]so your shell can correctly count its prompt's length - we recommend to highlight your prompt on production machines
- you can also [show different root prompts for each user](https://makandracards.com/makandra/9569-get-the-username-w...
Ruby and Rails deprecation warnings and how to fix them
Add deprecation warnings and their solution or link to available solutions.
Global access to Rake DSL methods is deprecated. Please include Rake::DSL into classes and modules which use the Rake DSL methods.
Open your Rakefile and add the following line above YourApp::Application.load_tasks:
YourApp::Application.class_eval do
include Rake::DSL
end
Use of ole/file_system is deprecated. Use ole/storage (the file_system api is recommended and enabled by default)...
CSS3 Pie: Element not properly redrawn
Pie sometimes does not properly redraw elements upon changes. This often happens when the change comes from somewhere further up the DOM.
Consider something like:
<ul>
<li class="active"><div class="content">Active element</div></li>
<li class="inactive"><div class="content">Inactive element</div></li>
</ul>
with CSS
li .content {
-webkit-box-shadow: #666 0px 2px 3px;
-moz-box-shadow: #666 0px 2px 3px;
box-shadow: #666 0px 2px 3px;
behavior: url(/PIE.htc);
back...
JavaScript Garden
JavaScript Garden is a growing collection of documentation about the most quirky parts of the JavaScript programming language. It gives advice to avoid common mistakes, subtle bugs, as well as performance issues and bad practices that non-expert JavaScript programmers may encounter on their endeavours into the depths of the language.
JavaScript Garden does not aim to teach you JavaScript. Former knowledge of the language is strongly recommended in order to understand the topics covered in this guide
RSpec matcher to check if an ActiveRecord exists in the database
The attached RSpec matcher exist_in_database checks if a given record still exists in the database and has not been destroyed:
describe Ticket do
describe '.purge_expired' do
fresh_ticket = Ticket.create(:expiry => Date.tomorrow)
expired_ticket = Ticket.create(:expiry => Date.yesterday)
Ticket.purge_expired
fresh_ticket.should exist_in_database
expired_ticket.should_not exist_in_database
end
end
Note that there is also [ActiveRecord::Base#destroyed?](http://apidock.com/rails/ActiveRecord/Base/destroyed...
ActiveRecord: Creating many records works faster in a transaction
When you need to insert many records into the same table, performance may become an issue.
What you can do to save time is to open a transaction and save multiple records within that transaction:
transaction do
500.times { Model.create! }
end
Although you will still trigger 500 INSERT statements, they will complete considerably faster.
When I tried it out with a simple model and 500 iterations, the loop completed in 1.5 seconds vs. 6 seconds without a transaction.
Alternative
Another fast way to insert many ...
Deal with different ways of counting weeks and weekdays in Ruby
Depending on where you live, different rules are used to determine the number of the week and a weekday. You have no chance whatsoever to get this right globally unless you make it your life's purpose. However, when you work for clients from Europe or the US, there are two dominantish standards you should know about. Each of these has subtle differences.
ISO 8601
- This is adhered to by most European countries.
- Weeks start on Mon...
Find records with a Range condition
You can find ActiveRecord models by using a Range as its conditions:
User.scoped(:conditions => { :id => 3..5 })
This will generate the following query:
SELECT * FROM `users` WHERE (`users`.`id` BETWEEN 3 AND 5)
This also means that all your scopes that take an array of allowed values and use condition hashes, automagically work for Ranges, too.
Output the descriptions of RSpec examples while they are running
In order to
- track down warnings and to see failing specs immediately
- or to get an overview of the core functionalities,
you can use RSpec's "nested" format. It looks like this:
Tool
validations
should require model to be set
should require place_id to be set
#identifier
should include the model and tag if the tool has a tag
should return the model if the tool has no tag
.search
should find tools by model and maker
should find tools by serial number
Call RSpec like...
Delete all MySQL records while keeping the database schema
You will occasionally need to clean out your database while keeping the schema intact, e.g. when someone inserted data in a migration or when you had to kill -9 a frozen test process.
Old Capybara versions already have the Database Cleaner gem as dependency. Otherwise add database_cleaner to your *Gemfile`. This lets you say this from the Rails console:
DatabaseCleaner.strategy = :truncation
DatabaseCleaner.cl...
Synchronize a Selenium-controlled browser with Capybara
When you click a link or a press a button on a Selenium-controlled browser, the call will return control to your test before the next page is loaded. This can lead to concurrency issues when a Cucumber step involves a Selenium action and a Ruby call which both change the same resources.
Take the following step which signs in a user through the browser UI and then sets a flag on the user that was just signed in:
Given /^the user "([^"]*)" signed in (\d) days ago$/ do |name, days|
visit new_session_path
fill_in 'Username', :w...
Unexpected behavior when changing both an association and its foreign key attribute in ActiveRecord
When you set both a record's association and that association's foreign key attribute, Rails does not realize you are talking about the same thing. The association change will win in the next save, even if the foreign key attribute was changed after the association.
As an example, assume you have these two models:
class Group < ActiveRecord::Base
has_many :users
end
class User < ActiveRecord::Base
validates_presence_of :group_id
belongs_to :group
end
We will now load a User and change both its `g...
Simple database lock for MySQL
Note: For PostgreSQL you should use advisory locks. For MySQL we still recommend the solution in this card.
If you need to synchronize multiple rails processes, you need some shared resource that can be used as a mutex. One option is to simply use your existing (MySQL) database.
The attached code provides a database-based model level mutex for MySQL. You use it by simply calling
Lock.acquire('string to synchronize on') do
# non-th...
Escaping of quotation marks in Cucumber steps and step definitions
Issue
When you have a Cucumber step like
Then I should see "Did you see those \"quotation marks\" over there?"
you'll run into trouble. Cucumber won't take your escaped quotation marks.
Workarounds
One workaround is to write the step as regex (since there is a step taking a regex):
Then I should see /Did you see those "quotation marks" over there\?/
Keep in mind it’s a regex – escape regex characters like '?'.
When you have a Cucumber step like
Then I should fill in "query" with "\"some phrase\""
The fo...
Maximum representable value for a Ruby Time object
On 32bit systems, the maximum representable Time is 2038-01-19 03:14:07 in UTC or 2038-01-19 04:14:07 in CET. If you try to instantiate a Time with any later value, Ruby will raise an ArgumentError.
If you need to represent later time values, use the DateTime class. This is also what Rails does when it loads a record from the database that has a DATETIME value which Time cannot represent. Note that there are some [subtle differences](http://stackoverflow.com/quest...
Dump your database with dumple
This tool is used on our application servers (and called when deploying) but it also works locally.
Just call dumple development from your project directory to dump your database.
This script is part of our geordi gem on github.
RSpec < 2.11: ActiveRecord scopes must be loaded before using the "=~" matcher
To test whether two arrays have the same elements regardless of order, you can use the =~ matcher in RSpec < 2.11:
actual_array.should =~ expected_array
If either side is an ActiveRecord scope rather than an array, you should call to_a on it first, since =~ does not play nice with scopes:
actual_scope.to_a.should =~ expected_scope.to_a
If you use RSpec >= 2.11 we recommend using the match_array or contain_exactly matchers instead of =~.
Use the eq matcher only if the order of records matters.
Validate an XML document against an XSD schema with Ruby and Nokogiri
The code below shows a method #validate which uses Nokogiri to validate an XML document against an XSD schema. It returns an array of Nokogiri::XML::SyntaxError objects.
require 'rubygems'
gem 'nokogiri'
require 'nokogiri'
def validate(document_path, schema_path, root_element)
schema = Nokogiri::XML::Schema(File.read(schema_path))
document = Nokogiri::XML(File.read(document_path))
schema.validate(document.xpath("//#{root_element}").to_s)
end
v...
Deploy and migrate with a single Capistrano command
Note that this sounds good but is not good at all when hooking tasks on cap deploy (see this article). Make sure to hook your calls properly when using this.
To deploy an application and run all pending migrations before restarting it, you can use the following standard Capistrano task:
cap deploy:migrations
Little is known what happens when the deployment goes through, but a migration or a rake task aft...
Speed up file downloads with Rails, Apache and X-Sendfile
When you use the send_file method to send a local file to the browser, you can save resources on the application server by setting the :x_sendfile option to true. This option is activated by default for Rails 3, so you need to understand this.
What this option does is not to send any data at all, but rather set the local file path as a new response header:
X-Sendfile: /opt/www/awesome-project/shared/downloads/image.png
When the response comes back from Rails to...
remove_index fails silently for non-existing indexes in Rails 2 migrations
When you try to remove a non-existing index using remove_index, the migration will incorrectly pass without an error. The schema will not be changed, but the migration will be considered migrated.
Since this might be fixed in the future, you cannot mend your database by adding another migration on top of the faulty one. You should manually alter the database schema to the previous migration on all machines that migrated the faulty migration (inform your fellow developers), then delete the faulty migration from the repository.
OscarGodson/jKey - GitHub
jQuery plugin to register callback functions to keyboard shortkuts. Keyboard events in vanilla Javascripts are super-painful to work with, so hopefully this library can help.