Rails 3 Remote Links and Forms: A Definitive Guide
Thanks to habits engrained by Rails 2’s link_to_remote and remote_form_for, we expect that Rails 3 would also handle the AJAX response for our remote links and forms. But it doesn’t; it leaves that for you.
Share your Internet connection under Ubuntu
This note describes how to setup a box running Ubuntu to share its Internet connection with another PC.
- You will need two network interfaces to do this. One will connect to the Internet (e.g. UMTS card), one will share the connection with the other PC (e.g. Wired LAN).
- On the Ubuntu PC, right-click on the connection symbol in the tray. Select Edit connections.
- Switch to the wired LAN card. Go to Edit and set the method to Shared to other computers.
- Connect the other PC to your wired LAN card. You can use the same cable that wo...
Terminus: a client-side Capybara driver
Terminus is a Capybara driver where most of the driver functions are implemented in client-side JavaScript. It lets you script any browser on any machine using the Capybara API, without any browser plugins or extensions.
Standalone Cucumber Test Suite
Sometimes you inherit a non Rails or non Rack based web app such as PHP, Perl, Java / JEE, etc. I like using cucumber for functional testing so I put together this project structure to use as a starting point for testing non Ruby web based applications.
Show a MySQL table's charset, collation and engine
Use this MySQL command to show further info about a table:
SHOW CREATE TABLE tags;
This will output a table schema like this:
CREATE TABLE `tags` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `index_tags_on_name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=60 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
Request a non-HTML format in controller specs
If a controller action responds to other formats than HTML (XML, PDF, Excel, JSON, ...), you can reach that code in a controller spec like this:
describe UsersController do
describe '#index' do
it 'should be able to send an excel file' do
# stubs and expectations go here
get :index, :format => 'xls'
end
end
end
Remember that both the :format
parameter and the HTTP_ACCEPT
header can m...
Get the current layout's name in a view or partial
This returns the name (including path) of your current layout:
response.layout
=> "layouts/admin" # inside views that are using the 'admin' layout
You most likely do not need the full path, so go ahead and do this:
File.basename(response.layout)
=> "admin"
Undocumented :inverse_of option for ActiveRecord associations
You can now add an :inverse_of option to has_one, has_many and belongs_to associations.... Without :inverse_of m and f.man would be different instances of the same object (f.man being pulled from the database again). With these new :inverse_of options m and f.man are the same in memory instance.
Enable or disable Gnome desktop icons
When doing a presentation you may want to hide your desktop icons.
You can switch them off (or back on) like this:
- Open up
gconf-editor
- Navigate to apps -> nautilus -> preferences
- (Un)check "show_desktop"
Fix LoadError with Rails 3 applications on Passenger
After switching to Rails 3 you may get a LoadError
with the following message when trying to use your application via passenger:
no such file to load -- dispatcher
Your Passenger version is most likely out of date.
Update the gem, then install the apache module again:
sudo gem install passenger
sudo passenger-install-apache2-module
Follow any instructions. Update your /etc/apache2/httpd.conf
with the lines given at the end of the installation process to use the version you just installed.
Passenger ignores RailsEnv directive for Rails 3 applications
You might find that your Passenger ignores all RailsSomething
directives in the vhost for your new Rails 3 application. The culprit is a file config.ru
which makes Passenger consider your application a Rack (non-Rails) application.
To fix this you can either use RackEnv
in lieu of RailsEnv
(it works fine) or delete the config.ru
. Unless you have a good reason to do so, go with RackEnv
.
Migrating to RSpec 2 from RSpec 1
You will need to upgrade to RSpec >= 2 and rspec-rails >= 2 for Rails 3. Here are some hints to get started:
- In RSpec 2 the executable is
rspec
, notspec
. - RSpec and rspec-rails have been completely refactored internally. All RSpec classes have been renamed from
Spec::Something
toRSpec::Something
. This also means that everyrequire 'spec/something'
must now berequire 'rspec/something'
. - In
spec_helper.rb
,Spec::Runner.configure
becomesRSpec.configure
- It has become really hard to extend specific example groups ...
Take care when merging with params
Be careful when using params.merge
as params
is a HashWithIndifferentAccess.
Why?
Usually this should not be an issue but it turns crazy if you try to include associated models deeper than 1 level:
options = params.merge(:include => { :user => :avatar })
Post.paginate options
When inspecting the merged params you will get something like this:
{ :include=> { "user" => :avatar }, :page => 23 }
Here the :user
symbol in the hash of inclusions turned into a "user"
...
Use form_for without the enclosing form tag
In rare cases you might need something like form_for
(for using form builder methods on the resulting block element) but without the surrounding form. One such case would be updating some of a form's fields via XHR.
You can simply use Rails' fields_for
to do things like this in your views (HAML here):
- fields_for @user do |form|
= form.label :email, 'E-Mail'
= form.text_field :email
You will only receive the form content you gave, no hidden inputs incl...
Shell script to quickly switch Apache sites
I prefer the application that I'm currently working on to be reachable at http://localhost/
.
So when I switch to another project, I use this handy shell script to set one site as the current one. Call it just like this:
apache-site makandra-com
Note that it disables all other sites in your Apache configuration so you would not want to use this on production machines.
Furthermore it will also enable the default
site if that was available.
When you call apache-site
with no arguments, it will list all available sites.
...
On memoizing methods that return a scope
Be careful when memoizing a method that returns a scope, e.g.:
def variants
scoped(:conditions => { :name => name })
end
memoize :variants
Because of the way memoize
is implemented, that method now no longer returns a scope but its loaded target array.
The best solution is to use the Memoizer gem instead.
A workaround is to roll your own memoization:
def variants
@va...
Generate a path or URL string from an array of route components
When using form_for
you can give the form's target URL either as a string or an array:
form_for(admin_user_path(@user)) do ... end
# same as:
form_for([:admin, @user]) do ... end
Same for link_to:
link_to("Label", edit_admin_user_path(@user))
# same as
link_to("Label", [:edit, :admin, @user])
polymorphic_path
and polymorphic_url
If you would like to generate a path or URL string from an array of route components just as form_for
does, you can use polymorphic_path
or polymorphic_url
:
polymorphic...
Adding a Timepicker to jQuery UI Datepicker
The timepicker addon adds a timepicker to jQuery UI Datepicker, thus the datepicker (jQueryUI) is required for using any of these. In addition all datepicker options are still available through the timepicker addon.
Falsehoods Programmers Believe About Names
I’m going to list assumptions your systems probably make about names. All of these assumptions are wrong. Try to make less of them next time you write a system which touches names.
Getting your e-mails back after upgrading Thunderbird to version 3
If you previously used version 2.x of Thunderbird and upgraded to 3.x (for example through an Ubuntu release upgrade) you might notice that Thunderbird will not show any of your old e-mails or settings.
This results from a different directory being used for storing profiles and configuration.
You can replace the blank profile with your old one like this:
cd ~
mv .thunderbird .thunderbird-invalid
cp -R .mozilla-thunderbird .thunderbird
Upon its next start, Thunderbird brings up the migration wizard introducing you to a few vers...
Working around the ancestry gem's way of object destruction
The ancestry gem allows you to easily use tree structures in your Rails application.
There is one somewhat unobvious pitfall to it: its way of applying the orphan_strategy
which defines how it handles children of an object going to be destroyed.
What's this all about?
In many cases you might want to disallow destruction if there are any child nodes present. The restrict
strategy does the trick but raises an exception when destroy
is called:
has_ancestry :orphan_st...
Inspecting model callback chains
If you need to look at the list of methods that are called upon certain events (like before/after saving etc), do this:
Model._save_callbacks.select {|cb| cb.kind == :before}.map{ |c| c.instance_variable_get :@filter }
Rails 2
User.after_save_callback_chain
To look at the method names only, you could do something like that:
User.after_save_callback_chain.collect(&:method)
Find the newest file from shell
This can be helpful when you need the latest file inside a directory for processing in a shell script:
ls -1tr * | tail -1
Used switches
The -1
switch makes ls
return 1 file per line, -t
orders by modification time and -r
causes sorting from oldest to newest. tail -1
then returns the last line, containing the newest file's name.
If you require only a subset of files, adjust the "*
" mask accordingly or use other switches of ls
.
Force RubyMine to notice file system changes
If you did file operations inside a shell or for example using Nautilus, it can take quite a while until RubyMine takes note of them and updates things like your project tree or its internal file list.
Flushing file system buffers helps you out (run it from a terminal):
sync
This is also possibly via the RubyMine menus: File → Synchronize.