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)...
Mocks and stubs in Test::Unit when you are used to RSpec
We are maintaining some vintage projects with tests written in Test::Unit instead of RSpec. Mocks and stubs are not features of Test::Unit, but you can use the Mocha gem to add those facilities.
The following is a quick crash course to using mocks and stubs in Mocha, written for RSpec users:
|---------------------------------------------------------|
| RSpec | Mocha |
|---------------------------------------------------------|
| obj = double()
| obj = mock()
|
| obj.stub(:method => 'value')
| `obj.stubs...
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...
Speed up response time in development after a Sass change
When working with large Sass files you will notice that the first request after a change to a Sass file takes quite some time. This is because the CSS files are being generated from the Sass files the moment the application answers your request (Sass looks at the files and recompiles if the timestamp changed); it takes even longer when you build sprites with the Lemonade gem.
To avoid this, have Sass watch the files for changes and compile them into CSS files immediately. Th...
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...
Why two Ruby Time objects are not equal, although they appear to be
So you are comparing two Time
objects in an RSpec example, and they are not equal, although they look equal:
expected: Tue May 01 21:59:59 UTC 2007,
got: Tue May 01 21:59:59 UTC 2007 (using ==)
The reason for this is that Time
actually tracks fractions of a second, although #to_s
doesn't say so and even though you probably only care about seconds. This means that two consecutive calls of Time.now
probably return two inequal values.
Consider freezing time in your tests so it is not dependent on the speed of the executi...
Check that a Range covers an element in both Ruby 1.9 and 1.8.7
In order to cover some edge cases you rarely care about, Range#include?
will become very slow in Ruby 1.9:
Range#include? behaviour has changed in ruby 1.9 for non-numeric ranges. Rather than a greater-than/less-than check against the min and max values, the range is iterated over from min until the test value is found (or max) [...] Ruby 1.9 introduces a new method Range#cover? that implements the old include? behaviour, however this method isn’t available in 1.8.7.
The attached ...
Fix Capistrano with RubyGems 1.6
After updating your RubyGems, you will probably not be able to run Capistrano any more, but receive an error similar to this:
can't activate net-ssh (= 2.0.22) for [], already activated net-ssh-2.1.0 for [] (Gem::LoadError)
If you have Bundler installed, you can use bundle exec
to avoid this problem as follows:
Create a gemfile at ~/.capistrano/Gemfile
(or at some other sensible place), that only contains these 2 lines:
source 'http://rubygems.org'
gem 'capistrano'
gem 'capistrano-ext' # You need this for multistag...
Closures in Ruby
If you want to get a deep understanding of how closures, blocks, procs & lambdas in Ruby work, check out the code at the attached link.
Here the summary:
^
---------------------------- Section 6: Summary ----------------------------
So, what's the final verdict on those 7 closure-like entities?
"return" returns from closure
True closure? or declaring context...? Arity check?
...
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.
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...
Testing if two date ranges overlap in Ruby or Rails
A check if two date or time ranges A and B overlap needs to cover a lot of cases:
- A partially overlaps B
- A surrounds B
- B surrounds A
- A occurs entirely after B
- B occurs entirely after A
This means you actually have to check that:
- neither does A occur entirely after B (meaning
A.start > B.end
) - nor does B occur entirely after A (meaning
B.start > A.end
)
Flipping this, A and B overlap iff A.start <= B.end && B.start <= A.end
The code below shows how to implement this in Ruby on Rails. The example is a class `Interv...
Dynamic conditions for belongs_to, has_many and has_one associations
Note: Consider not doing this. Use form models or vanilla methods instead.
The :conditions
option for Rails associations cannot take a lambda. This makes it hard to define conditions that must be evaluated at runtime, e.g. if the condition refers to the current date or other attributes.
A hack to fix this is to use faux string interpolation in a single-quoted :conditions
string:
class User < ActiveRecord::Base
has_many :contracts
has_one :current_contract, :class_name => 'Contract', :conditions => '...
Calling selected methods of a module from another module
Given those modules:
module A
def foo; end
def bar; end
end
module B
end
When you want to call methods from A
inside B
you would normally just include A
into B
:
module B
include A
end
Including exposes all of A
's methods into B
. If you do not want this to happen, use Ruby's module_function
: it makes a module's method accessible from the outside. You could put the module_function
calls into A
but it would remain unclear to peop...
Split an array into groups
Given group size
If you would like to split a Ruby array into pairs of two, you can use the Rails ActiveSupport method in_groups_of:
>> [1, 2, 3, 4].in_groups_of(2)
=> [[1, 2], [3, 4]]
>> [1, 2, 3, 4, 5].in_groups_of(2)
=> [[1, 2], [3, 4], [5, nil]]
>> [1, 2, 3, 4, 5].in_groups_of(2, 'abc')
=> [[1, 2], [3, 4], [5, 'abc']]
>> [1, 2, 3, 4, 5].in_groups_of(2, false)
=> [[1, 2], [3, 4], [5]]
Given group cou...
How to define constants with traits
When defining a trait using the Modularity gem, you must take extra steps to define constants to avoid caveats (like when defining subclasses through traits).
tl;dr
In traits, always define constants with explicit
self
.
If your trait defines a constant inside the as_trait
block, it will be bound to the trait module, not the class including the trait.
While this may seem unproblematic at first glance, it becomes a problem when including trai...
Access the documentation of all locally installed gems
In case https://www.rubydoc.info/ is to slow or offline, you can also read a gem documentation offline.
Start a server with gem server
and go to http://0.0.0.0:8808/
. Here you will find a list of all installed gems and it is possible to navigate to the documentation if installed e.g. http://0.0.0.0:8808/doc_root/rubocop-0.77.0/
In case you set the configured RubyGems to not install documentation by default, you need to add generate the documentation for the specific gem.
gem install rubocop --document
`...
ETags with memcached
I love ETags, but there’s something that annoys me: most implementations revolve around pulling a record out of a data store and only “rendering” the response if it hasn’t been modified.
The problem with this approach is that request has already gone through most of your application stack–parsing params, authentication, authorization, a few database lookups–so ETags are only saving you render time and some bandwidth.
While working on a Sinatra-based JSON web service that gets very heavy traffic, I wanted to find a way to short-circuit...
Always show the page if there is an error in Cucumber
Are you adding a "Then show me the page
" and re-run Cucumber whenever there is a failing scenario? Don't be that guy!
Save time with the shiny new version of our cucumber_spinner gem. It comes with a Cucumber formatter that not only displays an awesome progress bar, and shows failing scenarios immediately, it will also open the current page in your browser whenever a scenario step fails.
After you installed the gem, use the formatter like this:
cucumber --format CucumberSpinner::Curiou...
How to fix "extconf.rb:8:in `require': no such file to load -- mkmf (LoadError)"
If you're on Ubuntu:
sudo apt-get install ruby-dev
On other platforms: Look for a package containing ruby header files. On Red Hat that's "ruby-devel" likely.
Shell script to clean up a project directory
Call geordi clean
from a project root to remove unused and unnecessary files inside it.
This script is part of our geordi gem on github. In Geordi > 1.2 you can call geordi clean
.
Speed up RSpec by deferring garbage collection
Update: This trick probably isn't very useful anymore in Ruby 2.x. The Ruby GC has improved a lot over the years.
Joe Van Dyk discovered that running the Ruby garbage collector only every X seconds can speed up your tests. I found that deferring garbage collection would speed up my RSpec examples by about 15%, but it probably depends on the nature of your tests. I also tried applying it to Cucumber f...