How to inspect controller filter chains in specs
Sometimes you need to look at the filter chain in specs. You can do it like that on Rails 2:
controller.class.filter_chain.map(&:method)
Note that we need to look at the controller's class since before_filter
and after_filter
stuff happens on the class level.
Also mind that the above code will give you all filters, both those run before and after an action. You can query before?
and after?
on the filter objects to scope down to only some of them:
controller.class.filter_chain.select(&:before?).map(&:method)
For Rails 3, ...
Understanding the Selenium error "Modal Dialog Present" (aka Selenium::WebDriver::Error::UnhandledAlertError)
So your Cucumber feature sometimes dies with this exception:
Modal Dialog Present (Selenium::WebDriver::Error::UnhandledAlertError)
As a seasoned Selenium veteran you are used to misleading error messages. Hence you might be surprised that the reason for this particular error is that there is actually a modal dialog present and preventing Selenium from executing commands like click
or page.have_css?
.
How your code triggers this issue
The reason why a dialog is shown is somewhat fucked ...
Rails, callbacks, workers, and the race you never expected to lose « Logical Friday
How delayed jobs can make your after_save
callbacks execute before the record is saved.
MySQL: Can I speed up LIKE queries by adding an index?
For string columns, MySQL indexes the left side of a string. That means an index can speed a like query that has a wildcard on the right side:
SELECT * FROM foo WHERE field LIKE "bar%" # will be faster with an index
It can not speed up a query that has a variable left side:
SELECT * FROM foo WHERE field LIKE "%bar%" # will not be faster with an index
That also means if you use the ancestry gem you should index your ancestry
column if you use scopes like descendants
or `su...
RubyMine: Accessing views and partials from controllers
You can quickly access views that belong to a controller by using the tiny "page with arrow" icon in the gutter:
Access a method's view file
Click the icon next to the method definition in the controller.
If a view file does not yet exist, RubyMine will prompt you for its filename.
All views & partials associated to a controller
For a list of all views and partials that belong to the current ...
Why stubbing on associated records does not always work as expected
Be careful when stubbing out attributes on records that are defined by associations. Nothing is as it seems to be.
The associated record has its own universe of things; when delegating calls to it, you ca not stub methods on the associated record and expect them to be around. That is a general issue with this pattern/approach.
What's happening?
Consider these classes:
class Post < ActiveRecord::Base
belongs_to :thread
def thread_title
thread.title
end
end
class Thread < Acti...
Test your CSS rendering output with GreenOnion
No one wants to cry over regression issues in views; does testing HTML and CSS have to be such a back and forth between designers and devs? Why is it that the rest of the stack can have TDD and BDD but not the presentation layer? Well, GreenOnion is here to help you get the same results on testing front-end styling that you've enjoyed in your unit and integration tests up to now.
GreenOnion records 'skins', which are snapshots of the current state of a view (or any page that a browser can navigate to). The first time that it is run on a view...
Fix error: Missing the mysql2 gem
So you got this error, even though your Gemfile bundles mysql2
:
!!! Missing the mysql2 gem. Add it to your Gemfile: gem 'mysql2'
or
Please install the mysql adapter: `gem install activerecord-mysql-adapter` (mysql is not part of the bundle. Add it to Gemfile.)
The reason for this confusing error message is probably that your Gemfile says mysql2
, but your database.yml
still uses the mysql
adapter. Change it to use the mysql2
adapter:
development:
adapter: mysql2
database: myproject_developm...
MySQL 5.6 will expose tables as key/value stores through memcached, might be awesome
The next version of MySQL will include a built-in memcached daemon. This daemon can quickly get and set key/value pairs from and to InnoDB tables while completely bypassing the parsing and planning overhead of SQL.
This could potentially be very awesome because we would then have a distributed key/value store that stores data in a way it can also be queried with complex SQL queries.
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...
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...