Check if an object is an ActiveRecord scope
Don't say is_a?(ActiveRecord::NamedScope::Scope)
because that is no longer true in Rails 3 and also doesn't match unscoped ActiveRecord classes themselves (which we consider scopes for all practical purposes).
A good way is to say this instead:
object.respond_to?(:scoped)
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...
Updated: Remove quotes from Sass mixin arguments
When we looked at this card together a year ago, we were no longer sure if unquote
is actually useful. I now found a good example for when you need unquote
, and rewrote the card accordingly.
Updated: assignable_values can now humanize any given value, even if it's not the current attribute
You've always been able to access the humanized version for the current value like this:
song = Song.new(:genre => 'pop')
song.humanized_genre # => 'Pop music'
You can now also retrieve the humanized version of any given value by passing it as an argument:
song.humanized_genre('rock') # => 'Rock music'
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 |
+--------------------+----------+
Using the Rake Build Language
Rake (like make) allows you to add dependencies to a task after you've initially declared it. Indeed it allows you to continue to talk about a task in multiple places. This way I can decide to add dependencies close to the pre-requisite task.
When Date.today and Date.tomorrow return the same day...
... you probably have a time zone issue.
When you get
Timecop.travel(Date.parse("2011-11-11 00:00") do
Time.current # Thu, 10 Nov 2011 23:00:01 UTC +00:00
Time.now # Fri Nov 11 00:00:02 +0100 2011
Date.today # Fri, 11 Nov 2011
Date.tomorrow # Fri, 11 Nov 2011
end
you probably haven't defined a zime zone yet.
So might fix this by adding the following lines to your application.rb
:
class Application < Rails::Application
config.time_zone = 'Berlin' # or whatever your time zone
end
It se...
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 ...
MySQL operator precedence
Take care in queries where multiple AND or OR operators are used. In doubt, always use braces to enforce precedence.
Asset pipeline for Rails 2
The asset pipeline from Rails 3.1 packported to 2.3. By Michael Grosser from parallel_tests fame.
Request limit of graph.facebook.com
The facebook API allows up to 600 requests per 600 seconds.
If you poll more often, you'll get no or malformed answers.
PhoneGap Build
Write your app using HTML, CSS or JavaScript, upload it to the PhoneGap Build service and get back app-store ready apps for Apple iOS, Google Android, Windows Phone 7, Palm, Symbian, BlackBerry and more.
By compiling in the cloud with PhoneGap Build, you get all the benefits of cross-platform development but can still build apps just the way you like.
Drag'n'drop in trees: I went to town
For my Gem Session project Holly I ran the Ironman of drag'n'drop implementations:
- Dragging in nested lists
- User-definable order of items
- Complicated item elements with super-custom CSS and other Javascript functionality
- Items that can be both leaves and containers of other items
- has_ancestry on the server side
Things I learned:
- Be ready to write a lot of CSS. You need to indicate what is being dragged, where it will be dropped, if it is dropped above, below o...
Nice way to set data attributes when creating elements with Rails helpers
You can say this in helpers like link_to
and content_tag
:
= link_to 'Label', root_url, :data => { :foo => 'bar', :bam => 'baz' }
This will produce:
<a href="/" data-foo="bar" data-bam="baz">Label</a>
Only works in Rails 3. In Rails 2 you do
= link_to 'Label', root_url, 'data-foo' => 'bar', 'data-bam' => 'baz' }
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.
jQuery.cssHooks – jQuery API
The $.cssHooks object provides a way to define functions for getting and setting particular CSS values. It can also be used to create new cssHooks for normalizing CSS3 features such as box shadows and gradients.
For example, some versions of Webkit-based browsers require -webkit-border-radius to set the border-radius on an element, while earlier Firefox versions require -moz-border-radius. A css hook can normalize these vendor-prefixed properties to let .css() accept a single, standard property name (border-radius, or with DOM property synt...
Updated: Capybara: Check that a page element is hidden via CSS
- The step we used in the past (
Then "foo" should not be visibile
) doesn't reliably work in Selenium features. - I overhauled the entire step so it uses Javascript to detect visibility in Selenium.
- The step has support for jQuery and Prototype projects, so it should be a drop-in replacement for all your projects.
- For Rack::Test the step no longer uses XPath so you should be able to understand it when you are not a cyborg :)
- There were some other cards detailing alternative steps to detect visibility. I deleted all these other cards s...
Update Skype 4.x to at least 4.0.0.8
There was a bug in Skype that could cause messages to be sent to incorrect recipients (anyone, not only people from your contact list).
If you were using Skype 4 on Linux (or Skype on any other platform), upgrade immediately.
I don't know if Skype 2 on Linux is affected.
Updated: Check whether an element is visible or hidden with Javascript
- Added information about what jQuery considers "visible"
- Added a solution for Prototype
- Added a patch for Prototype that replaces the useless
Element#visible()
method with an implementation that behaves like jQuery.
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 ...
Click on a piece of text in Cucumber / Capyabra
The step definition below lets you write:
When I click on "Foo"
This is useful in Selenium features where the element you click on is not necessarily a link or button, but could be any HTML element with a Javascript event binding.
The easiest way to get this step is to use Spreewald. If you would like to add it manually, here is the step definition:
When /^I click on "([^\"]+)"$/ do |text|
matcher = ['*', { :text => text }]
element = page.find(:css, *matcher)
while be...
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...