New geordi script: migrate-all
Use the command geordi migrate
to migrate your databases and to prepare them before running tests. The abbrevation geordi m
works as well.
- It will run
rake db:migrate
if parallel_tests does not exist in your Gemfile - Otherwise it runs
b rake db:migrate
and then executesb rake parallel:prepare
if parallel_tests was found in your Gemfile.
How to revert features for deployment, merge back, and how to stay sane
Removing features and merging those changes back can be painful. Here is how it worked for me.\
tl;dr: Before merging back: reinstate reverted features in a temporary branch, then merge that branch.
Scenario
Consider your team has been working on several features in a branch, made many changes over time and thus several commits for each feature.\
Now your client wants you to deploy while there are still stories that were rejected previously and can't be deployed.
...
Improved gitpt now part of geordi
Our gitpt
script to generate git commits from Pivotal Tracker stories has been tweaked and polished and is now part of the geordi gem.
Install the freshly released version 0.7 now:
gem install geordi
This update will bring you commit
with an initial "setup wizard" (that asks for your PT API key and initials) and prettier output: stories are colored by their state and thos...
CSS box-shadow not working in IE9 inside tables with collapsing borders
Though Internet Explorer 9 supports the box-shadow
CSS property there is a nasty bug which sometimes prevents it from rendering the shadow properly.
Consider this HTML:
<table style="border-collapse: collapse">
<tr>
<td>
<div style="box-shadow: 0 0 10px #f00">Hello universe</div>
</td>
</tr>
</table>
While it works in other browsers, IE9 is not showing any shadow. For some reason, it requires border-collapse: separate
for the table to be set:
<table style="border-collapse: separate" c...
Don't compare datetimes with date ranges in MySQL and PostgreSQL
When selecting records in a date range, take care not to do it like this:
start_date = Date.parse('2007-05-01')
end_date = Date.parse('2007-05-31')
LogItem.where(:created_at => start_date .. end_date)
The problem is that created_at
is a datetime (or Time
in Ruby), while start_date
and end_date
are simple dates. In order to make sense of your query, your database will cast your dates to datetimes where the time component is 00:00:00
. Because of this the query above will lose records created from `2007-05-31 00:00:0...
Use Time.current / Date.current / DateTime.current on projects that have a time zone
Basically, you now need to know if your project uses a "real" time zone or :local
, and if config.active_record.time_zone_aware_attributes
is set to false
or not.
-
With time zones configured, always use
.current
forTime
,Date
, andDateTime
.ActiveRecord attributes will be time-zoned, and
.current
values will be converted properly when written to the database.
Do not useTime.now
and friends. Timezone-less objects will not be converted properly when written to the database. -
With no/local time zone use
Time.now
, `...
acts_as_taggable_on: Match records tagged with all, any or none of the given tags
The tagged_with
scope comes with many awesome options to modify your search:
User.tagged_with("awesome", "cool") # Users that are tagged with awesome and cool
User.tagged_with("awesome", "cool", :exclude => true) # Users that are not tagged with awesome or cool
User.tagged_with("awesome", "cool", :any => true) # Users that are tagged with awesome or cool
User.t...
Always sort lists that are visible in the UI
This might seem obvious, but I'm rejecting stories because of this on a regular basis.
Whenever a list (e.g. an index of records or the options of a select box) is visible in the UI that list must be sorted. Unsorted lists are completely unusable once they contain more than 5 items.
Make Less interpret the escape codes in a logfile
The unix command line tool less is a good choice for browsing logfiles. In the standard configuration, though, it does not interpret the escape sequences used in the rails logfiles. To enable this type:
less -R my_logfile.log
You can also have an alias to save yourself the typing
alias less='less -R'
Managing Rails locale files with i18n-tasks
When internationalizing your Rails app, you'll be replacing strings like 'Please enter your name'
with t('.name_prompt')
. You will be adding keys to your config/locales/*.yml
files over and over again. Not to miss any key and place each at the right place is a challenging task.
The gem i18n-tasks
has you covered. See its README for a list of things it will do for you.
Note
The
i18n-tasks
gem does not understand aliases and will duplicate all referenced data when it writes locales. If yo...
Useful script to collect downloads from several sites
For university I have to stay up-to-date with lecture documents. Since my university doesn't offer RSS feeds, I wrote a little script that collects files from web pages.
You want this, if you have several web pages that offer downloads that you don't want to check manually. Just register the URL and a CSS snippet to retrieve the files in the attached script and run it – it will fetch all your files. It will store all files in a single place or sort them into respective directories.
Edit the header of the file (providing your data), save it...
Graticule computes NULL distance for some records (and how to fix that)
The SQL code generated by Graticule's spherical distance computation is insufficient and can lead to NULL
distances in edge cases.
The reason for this is that MySQL is performing several sine and cosine computations which can result in slight rounding errors -- which is usually okay. Rarely, though, for the exact center of the given circle, it is then asked to compute the arc cosine of a result like 1.0000000001.
Since this i...
Sequel: The Database Toolkit for Ruby
Seems like a useful gem for cases where ActiveRecord is overkill but you don't want to do everything by hand either.
Bulk-change multiple table rows in a migration
Using rename_column
, remove_column
, etc. more than once in a migration makes that migration run slower than it should. Use change_table
instead.
Consider this migration:
add_column :users, :name, :string
remove_column :users, :first_name
remove_column :users, :last_name
rename_column :users, :cool, :awesome
Migrating in this case means that all those commands are processed step by step, causing 4 SQL statements to change the table. In turn, your database needs to modify the table structure 4 times. When working on hu...
ActsAsTaggableOn: Cache tag lists
For performance improvements (and to remove the need for eager loading), the ActsAsTaggableOn gem supports caching your tag lists directly in your model. To enable this, simply add a cached_tag_list
column to your table.
Example:
class Company < ActiveRecord::Base
acts_as_taggable_on :categories
end
The cache column has to be named cached_category_list
.
Existing data
If you already have existing data, you have to save all records with tags once, after you've added the ...
Find geocoded records that are close to a location (radius search)
When you have objects in your database that hold latitude and longitude and you want to find others that are close to given coordinates you can use the Graticule gem.
Graticule
Graticule offers several methods to compute the distance between two geo-dated objects but fetching records from the database that are within a given radius of a location is a bit trickier:
def close_destinations(latitude, longitude)
distance_sql = Graticule::Distance::Spherical.to_sql(:latitude => l...
Preparing your test database: mind the differences
Instead of running all missing migrations on your test database with rake db:migrate RAILS_ENV=test
you can also use a handful of rake tasks to prepare the database structure directly. They can produce different results, though.
In a nutshell, to ensure your test database gains the correct structure:
- Don't use
rake db:test:prepare
carelessly - or use
rake db:test:clone_structure
← preferred :) - or use
rake db:migrate RAILS_ENV=test
and don't mix it with other ways, like some of the rake tasks.
rake db:test:prepare
------------...
state_machine: Test whether an object can take a transition
When using state_machine you sometimes need to know whether an object may execute a certain transition. Let's take an arbitrary object such as a blog article as an example that has those states:
A -> B -> C -> D
Additionally, you have transitions between the states as shown above. Let's call the transition between 'A' and 'B' transition_ab
for simplicity. \
Given an object in state 'A'. You can call object.transition_ab
but calling object.transition_bc!
will obviously fail because ...
Large forms are slow on the iPad
- Forms with many inputs (600+ in my case) become extremely unresponsive on an iPad, up to the point where it can take several seconds for a control to respond to touch commands.
- This is true for both iPad 1 and iPad 2 models.
- While certain CSS styles can lead to performance issues, removing those styles won't help if the form simply is very large.
- A workaround is to only show a limited number of form inputs at the time, e. g. by toggling groups of form...
jQuery 1.7 Released
Two new methods on
and off
are the new way of declaring event handlers. bind
, delegate
and live
area deprecated. Also better performance for delegated events.
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...
Change the MySQL default character set on Amazon Relational Database Service (RDS)
Look here for informations how you can show the MySQL default character set.
At first you need the Amazon RDS Command Line Toolkit
- download and unzip the [Amazon RDS Command Line Toolkit](http://aws.amazon.com/developertools/A...
Improve web font rendering in Windows by autohinting fonts
Web fonts are awesome. After being restricted to Arial for two decades there is finally a cross-browser way to embed fonts into web pages.
Unfortunately while web fonts look awesome on Linux and MacOS, they look horrible on Windows, a problem that gets worse with smaller font sizes.
The culprit is something called font hinting:
...