New Cucumber Factory makes it easier to associate records
I pushed a new version of the Cucumber Factory gem. This new release lets you refer to a previously created record by any string attribute:
Given there is a movie with the title "Before Sunrise"
And there is a movie with the title "Limitless"
And there is a movie with the prequel "Before Sunrise"
Note how we didn't have to explicitly give the prequel a name in the example above. This is still possible, but will rarely be necessary now:
Given "Before Sunrise" is a movie with...
Dynamically skip Capistrano hooks
When you have a hook in your Capistrano file that dumps your remote database, you might not want it to dump each time you deploy (say, you're experimenting with staging and don't want ten dumps an hour). How to skip dump creation:
Capistrano 2
In your Capistrano file:
before 'deploy:update_code', 'db:dump' unless fetch(:skip_dump, false)
The second parameter of fetch sets a default value if skip_dump is not defined.
In your terminal:
cap staging deploy -S skip_dump=true
The -S must be a capital letter t...
Merging two arbitrary ActiveRecord scopes
(Rails has a method ActiveRecord::Relation#merge that can merge ActiveRecord scopes. However, its behavior has never been clear, and in Rails 7 it still discards conditions on the same column by the last condition. We discourage using #merge!)
The best way to merge ActiveRecord scopes is using a subquery:
scope_a.where(id: scope_b)
It is a little less concise than #merge, but unambiguous.
Example
Assume a model where a deal has many documents:
class Deal < ApplicationRecord
has_many :...
SSL: Build a Certificate signing request (CSR)
In order to request a SSL certificate from any dealer, you usually need a CSR certificate. As both the CSR as well as key are created in this step, make sure you save this certificate on a trusted, secure machine only. Usually this is your production environment.
Run this on the server (not on your machine) as root.\
Replace your-domain.tld with the domain you request the certificate for and YYYY with the current year so you will not have any conflicts when requesting a certificate next year.
openssl req -new -sha256 -out www.your-dom...
Semantic markup standard for search engines
If you would like to enrich your website with semantic markup like contact data, places or events you should have a look at schema.org. "Search engines including Bing, Google and Yahoo! rely on this markup to improve the display of search results, making it easier for people to find the right web pages."
The following example from the schema.org documentation shows you how to describe a movie with semantic markup:
<div itemscope itemtype ="http://schema.org/Movie">
<h1 itemp...
Enable soft tabs in Vim
If you want to enforce soft tabs (spaces instead of tabstops) in Vim put this into your ~/.vimrc (Linux) or C:\Users\<Username>\_vimrc (Windows):
set tabstop=2
set softtabstop=2
set shiftwidth=2
set expandtab
You can also call those commands in a running Vim instance (using ":set ...") to switch on soft tabs temporarily.
On a side note: remember the :mkvimrc command that saves active settings to a vimrc file.
Find records created within a timespan
Put the attached file into config/initializers/ to be able to say created_within on any ActiveRecord or its scope chain. This will return a scope of all records created between two given timestamps.
Use it like that:
Booking.created_within(1.year.ago, Date.yesterday).count
User.active.created_within(1.hour.ago, DateTime.now)
It explicitly looks at the database table name so you are usually fine when joining other tables.
Defining host aliases in your SSH config
You probably already manage servers you often connect to inside the ~/.ssh/config file. What is nice: you may define alias names for hosts so that you can say something like ssh foobar-staging.
This is especially helpful for servers whose hostnames are hard to remember or who don't have a DNS record at all (and must be accessed via their IP address).
To achieve the above, you can define something like this in your ~/.ssh/config:
Host foobar-staging
Hostname staging.example.com
Note that SSH will only match this for `ssh f...
How to employ and run your tests with parallel_tests to speed up test execution
When your cucumber features grow massively over time, the test execution can take a lot of time.
One easy way to speed up your test execution is to use the parallel_tests gem.
It comes along with some useful rake tasks that let you setup your local test environment shortly to run your features, specs or unit-tests in parallel.
Follow these steps to get it to work.
-
Add the parallel_tests gem to your
Gemfiletest sections like that:# ./Gemfile group :development, :test do
...
Script to create and copy a production dump to your project root
Soon after having written our shell-for script, we wanted to easily get dumps of our productions machines, too. This is how we do it:
dump-for staging [-s]
It will copy the dump to your project's tmp directory and name it according to the capistrano stage you're calling for, here: staging.dump. When you pass the optional -s option, the dump will automatically been sourced into your local development database.
This script ...
Releasing geordi
After having written useful scripts into makandra notes for a long time, we’ve now tied them into a powerful new gem: geordi.
It gives you the power to
- get a dump from your production database with
dump-for production - install your local gems to the production machine with
install-gems-remotely - execute rake tasks to several environments at the same time with
power-rake db:migrate - and much more
Rails 3.1: Release candidate
Asset pipeline, HTTP streaming, jQuery as default framework, auto-reversable migrations, identity map for ActiveRecord.
Ruby 1.8.x support will be dropped with or after Rails 4.
Fix randomly failing PDF cucumber tests
Sometimes PDF cucumber tests fail at the first test run and succeed at the second run. You can fix this with this step:
When PDF generation is ready
And I follow "Save as PDF"
# Checks for PDF contents go here
Here is the step definition:
When /^PDF generation is ready$/ do
Then 'I should see ""'
end
Setting up Ubuntu Server as Virtual Machine in VMware
Install Ubuntu Server
- Download an image from this site
- Select
File > New…to and follow the instructions, choose the.isofile you downloaded as image file - Deselect "Simple installation" – you want to configure your system yourself
- Start the new virtual machine and follow the instructions
Install VMware Tools
- Choose
Virtual Machine > Install VMware Toolsfrom the VMware menu, then:
^
# install required packages
sudo apt-get install build-essential psmisc
# m...
Validations on associated objects
Validations that need to access an associated object may lead to some trouble. Let's exemplify that using this example:
class Project < ActiveRecord::Base
has_one :note
end
class Note < ActiveRecord::Base
belongs_to :project
end
Now say we need a validation that ensures that a description is set (validates_presence_of :description) within Note but only if the Project has a flag called external set to true. The following code will lead to some problems as the associated object is not present when creatin...
Use find_in_batches or find_each to deal with many records efficiently
Occasionally you need to do something directly on the server -- like having all records recalculate something that cannot be done in a migration because it takes a long time.
Let's say you do something like this:
Project.all.each(&:recalculate_statistics!)
Even though you may have been successful with this on your development machine or the staging server, keep in mind that production machines often hold a lot more records. Using all may just work, even with lots of records, but when you iterate over such records and fetch a...
Speed up Capistrano deployments using a remote cached copy of repository
You can seriously speed up deployments with Capistrano when using a local git repository on the server you are deploying to.
Simply add
set :deploy_via, :remote_cache
set :copy_exclude, [ '.git' ]
to your config/deploy.rb and Capistrano will create a clone in shared/cached-copy. This will be updated using git pull when deploying which transfers less bytes and is usually much faster. If deploy_via is set to use default settings (being "export"), Capistrano will do a full clone of the repository from your git host otherwi...
BigDecimal arithmetic in Ruby
Ruby comes with a class BigDecimal which you can use for arbitrary precision arithmetic. You should use BigDecimal instead of Float whenever you care about rounding errors, e.g. whenever you are dealing with money.
You should remember these two rules when working with BigDecimal values:
- When you add or multiply a
BigDecimalwith anotherBigDecimal, the ...
How DECIMAL columns deal with numbers exceeding their precision or scale
When storing floating-point numbers such as prices or totals in an SQL database, always use a DECIMAL column. Never use FLOAT or kittens will die.
DECIMAL columns are parametrized with a precision and a scale. These parameters describe which numbers can be stored in that column. E.g. a decimal with a precision of 5 and a scale of 2 can store numbers from -999.99 to 999.99, but not 1000 or 1.234.
This card explains what various databases do when you try to store a number in a DECIMAL field, and that number exceeds that colum...
Capistrano 2: Which Capistrano hooks to use for events to happen on both "cap deploy" and "cap deploy:migrations"
When deploying an application with "cap deploy" by default [1] you only deploy your code but do not run migrations. To avoid an application to be running with code which requires database changes that did not happen yet you should use cap deploy:migrations.
The problem
Let's say that you have something like that in your config/deploy.rb to create a database dump every time you deploy:
before 'deploy', 'db:dump'
This will not be called for cap deploy:migrations. The same applies to other things that are ho...
Saving application objects in your session will come back to haunt you
If you save a non-standard object (not a String or Fixnum, etc) like the AwesomeClass from your application in the session of visitors be prepared that some time you will get this exception:
ActionController::SessionRestoreError: Session contains objects whose class definition isn't available. Remember to require the classes for all objects kept in the session. (Original exception: ...)
This happens when you remove your AwesomeClass but users come back to your site and still have the serialization of such objects in their session....
Collect an array of IDs from any object
The Edge Rider gem will define a method collect_ids on your ActiveRecord models, scopes, integer scalars and collections, which will return a list of their IDs:
User.last.collect_ids # => [9]
[User.first, User.last].collect_ids # => [1, 9]
User.active.collect_ids # => [4, 5, 6]
[4, 5, 6].collect_ids # => [4, 5, 6]
7.collect_ids #=> [7]
This allows you to parametrize scopes with a variety of argument types:
class Note < ActiveRecord::Base
named_scope :for_users, lamb...
Why preloading associations "randomly" uses joined tables or multiple queries
ActiveRecord gives you the :include option to load records and their associations in a fixed number of queries. This is called preloading or eager loading associations. By preloading associations you can prevent the n+1 query problem that slows down a many index view.
You might have noticed that using :include randomly seems to do one of the following:
- Execute one query per involved table with a condit...
Retrieve the SQL query a scope would produce in ActiveRecord
Rails 3
User.active.to_sql
Rails 2
Use either the Edge Rider or fake_arel gem to get #to_sql backported to Rails 2.
If you don't want to use a gem for this, you can do this with vanilla Rails 2:
User.active.construct_finder_sql({})