assignable_values 0.4.1 adds secondary default values
assignable_values now lets you define a secondary default that is only used if the primary default value is not assignable:
class Song < ActiveRecord::Base
assignable_values_for :year, :default => 1999, :secondary_default => lambda { Date.today.year } do
(Date.today.year - 2) .. Date.today.year
end
end
If called in 2013 the code above will fall back to:
Song.new.year # => 2013
This is especially useful in authorization scenarios with [Consul](https://github....
Use the "paper_trail" gem to track versions of records
paper_trail
is an excellent gem to track record versions and changes.
You almost never want to reimplement something like it yourself. If you need to log some extra information, you can add them on top.
It comes with a really good README file that holds lots of examples. I'll show you only some of its features here:
-
- Setting up a model to track changes
- Just add
has_paper_trail
to it:
class User < ActiveRecord::Base
has_paper_trail
end
-
- Accessing a previous version
- Saying
user.previous_version
gi...
How to change will_paginate's "per_page" in Cucumber features
The will_paginate
gem will show a default of 30 records per page.
If you want to test pagination in a Cucumber feature, you don't want to create 31 records just for that.
Instead, you probably want to modify the number of items shown, by saying something like this:
Given we paginate after 2 users
Using the following step definition, you now can! :)
require 'cucumber/rspec/doubles'
Given /^paginate after (\d+) (.*)$/ do |per_page, model_name|
model = model_name.singularize.gsub(/...
Maximum size of a MySQL query
Unless you changed the default, this will be 16 MB:
mysql> SHOW VARIABLES WHERE Variable_name="max_allowed_packet";
+--------------------+----------+
| Variable_name | Value |
+--------------------+----------+
| max_allowed_packet | 16777216 |
+--------------------+----------+
When connecting to a second database, take care not to overwrite existing connections
Sometimes, you may want to open up a second database connection, to a read slave or another database. When doing that, you must make sure you don't overwrite an existing connection.
The problem
While this may look good, it will actually cause all kinds of trouble:
def with_other_database
ActiveRecord::Base.establish_connection(slave_settings)
yield
ensure
ActiveRecord::Base.establish_connection(master_settings)
end
Putting aside that you are setting the general connection here (not generally a ...
How to enable MySQL query logging
This will make MySQL log all received queries so you can see for yourself what happens on the database level.
Don't switch this on for production machines!
- Edit your
my.cnf
:
sudo vim /etc/mysql/my.cnf - In the
[mysqld]
section, add:
log=/var/log/mysql.log - Restart your MySQL daemon. On Ubuntu:
sudo service mysql restart
Note that your MySQL performance will suffer. But when you need to enable query logging for a debug fest, you probably don't care about that.
RubyMine: Using pinned tabs will increase your productivity
I highly recommend that you make use of RubyMine's feature to pin tabs.
When you pin all "important" files, you can follow method definitions, wildly open files from search results and have a ton of open tabs -- without the problem of finding the stuff you were working on before.
Guide
- Pin the tabs of files that are currently in the focus of your work (important models, specs, etc):
- Right-click a tab and select "Pin tab"
- Or use a shortcut (see below)
- Work as usual.
- Once you opened other tabs because you searched ...
Speed up large Cucumber test suites
Test suites usually grow over time as more and more development time is spent on a projects. Overall run-time and performance of Cucumber suites in turn increases, too.
You can use the very same way Henning suggested for speeding up RSpec some time ago.
Put the following into features/support/deferred_garbage_collection.rb
Before do
DeferredGarbageCollection.start
end
After do
DeferredGarbageCollection.reconsider
end
We...
Rails 3.1 gives you free down migrations
In Rails 3.1+, instead of defining a separate up
and down
method you can define a single method change
:
class AddComparisonFieldsToReport < ActiveRecord::Migration
def change
add_column :reports, :compare, :boolean
update "UPDATE reports SET compare = #{quoted_false}"
add_column :reports, :compare_start_date, :date
add_column :reports, :compare_end_date, :date
end
end
Migrating up works as expected:
b rake db:migrate
== AddComparisonFieldsToReport: migrating ====================================
-- ad...
Updated: Preload associations in loaded records
I ported the initializer to Rails 3.
Mysql/Mysql2 agnostic database.yml
If you upgrade to the mysql2 gem, you will run into the problem that the server's database.yml (which is usually not under version control) needs to change exactly on deploy.
You can however make your database.yml work for mysql and mysql2 at the same time. Simpy do this
production:
adapter: <%= defined?(Mysql2) ? 'mysql2' : 'mysql' %>
#...
Solve Flash performance issues in Ubuntu
The linked article describes how to use a Firefox addon "Flash-Aid" to install a better build of Flash and apply some optimizations.
With this I can now properly watch fullscreen HD videos under Ubuntu.
Geordi: Use load-dump script to source a database dump into your database
This script loads a dump into your development database.
You can provide the full path to you database dump like this:
load-dump path/to/my.dump
When you call load-dump
without any arguments it will show a menu with all dumps in your ~/dumps/
folder.
load-dump
This script is part of our geordi gem on github.
Rails asset pipeline: Why relative paths can work in development, but break in production
The problem
When using the asset pipeline your assets (images, javascripts, stylesheets, fonts) live in folders inside app
:
app/assets/fonts
app/assets/images
app/assets/javascripts
app/assets/stylesheets
With the asset pipeline, you can use the full power of Ruby to generate assets. E.g. you can have ERB tags in your Javascript. Or you can have an ERB template which generates Haml which generates HTML. You can chain as many preprocessors as you want.
When you deploy, Rails runs assets:precompile
...
Loading half a billion rows into MySQL
Some advice for bulk loading many records into InnoDB and finishing before the sun burns out. Use with care.
IE-friendly mobile-first CSS with Sass 3.2
Building CSS mobile-first is the way forward, because blah blah blah progressive enhancement blah. Problem is, Internet Explorer prior to 9 ignores anything within media query blocks, leaving those browsers with mobile styles.
Not all of us can get away with that, but thankfully, as Chris Eppstein points out, Sass 3.2 (not yet released) can generate a separate stylesheet with everything it needs to create a "desktop" look.
This page was built mobile-first where smaller width devices get a single column layout, but IE8 and below still get a...
How could it be that my database.yml disappears?
Probably was in the repository once and got deleted in a commit that you pulled.
Plotting graphs in Ruby with Gruff
Geoffrey Grosenbach has created Gruff for easily plotting graphs. It is written in pure Ruby and integrates with Rails applications.
It provides features as automatic sizing of dots and lines (the more values, the thinner the graph's elements), custom or predefined themes, different styles (bar, line, dot and many more) and multiple graphs in one chart.
Installation
In your Gemfile:
gem 'rmagick', :require => false
gem 'gruff'
Then run bundle install
(and don't forget to restart your development server.)
Usage
This i...
The Ruby Toolbox – a collection of good gems
If you need a gem for a certain purpose, be sure to check this site.
The rankings are determined by counting up the number of forks and watchers of various github projects, so I'd view it less as "this is what I should be using," and more as "these are some things I should check out." At the very least, they're all likely to be under active development and fairly up to date, and it's very useful to see groups of gems broken down by category.
Guide to localizing a Rails application
Localizing a non-trivial application can be a huge undertaking. This card will give you an overview over the many components that are affected.
When you are asked to give an estimate for the effort involved, go through the list below and check which points are covered by your requirements. Work with a developer who has done a full-app localization before and assign an hour estimate to each of these points.
Static text
- Static strings and template text in
app
must be translated: Screens, mailer templates, PDF templates, helpe...
MySQL 5.1: Switch to InnoDB Plugin for better performance
MySQL version 5.1 comes with an alternative, faster InnoDB implementation (called "InnoDB Plugin").
Switching is easy:
- Stop your mysqld with
sudo stop mysql
- Add the following lines to your
/etc/mysql/my.cnf
under the[mysqld]
section
ignore-builtin-innodb
plugin-load=innodb=ha_innodb_plugin.so - Start your mysqld with
sudo start mysql
The file format has not changed, your tables should survive this.
Note: This is not necessary in MySQL 5.5, where the new implementation is the default.
How to use pessimistic row locks with ActiveRecord
When requests arrive at the application servers simultaneously, weird things can happen. Sometimes, this can also happen if a user double-clicks on a button, for example.
This often leads to problems, as two object instances are modified in parallel maybe by different code and one of the requests writes the results to the database.
In case you want to make sure that only one of the requests "wins", i.e. one of the requests is fully executed and completed while the other one at least has to wait for the first request to be completed, you ha...
When using time zones, beginning_of_day / end_of_day is broken in Rails 2 for any Date or DateTime
Using beginning_of_day
or end_of_day
on Date
or DateTime
objects in Rails 2.x applications will never respect time zones, which is horrible.\
This is fixed in Rails 3, though.
Even when using Date.current
or DateTime.current
you will get regular Time
or DateTime
objects:
>> Date.current.beginning_of_day.class
=> Time # not a ActiveSupport::TimeWithZone as expected
>> DateTime.current.beginning_of_day.class
=> DateTime ...