Defining and using sub-classes with modularity
Given this class:
class Foo
class Bar
end
end
If you want to clean up this code with the modularity gem, you might try something like this:
class Foo
does 'bar'
end
module BarTrait
as_trait do
class Bar
end
end
end
Note that this changes Bar
's full class name from Foo::Bar
to BarTrait::Bar
. If you have methods inside Foo
(or other classes), you would have to change all references accordingly, which is quite unpleasant.
You can solve it like that:
`...
Install gems for all bundled projects
This is a bash script for those of you who need to install all gems for all projects (e.g. to get started quickly on a newly installed system).
Put it into your ~/bin/
and run it from the directory that holds your projects.
Note that, like the vanilla bundle install
, this will fail whenever a new gem compiles native components and requires a missing system dependency.
Select a random table row with ActiveRecord
Use this scope:
class Stick
named_scope :shuffled, lambda {
last_record = last
{ :conditions => [ 'id >= ?', rand(last_record.id) ] } if last_record
}
end
You can now pick a random stick by saying
Stick.shuffled.first
Or, if you prefer something smaller:
class Stick
named_scope :shuffled, :order => 'RAND()'
end
Note however that you should never order by RAND()
on tables that may become large some day, as this performs horribly and can kill your database server.
Test that a CSS selector is present with Cucumber
This note describes a Cucumber step definition that lets you test whether or not a CSS selector is present on the site:
Then I should see an element "#sign_in"
But I should not see an element "#sign_out"
Here is the step definition for Capybara:
Then /^I should (not )?see an element "([^"]*)"$/ do |negate, selector|
expectation = negate ? :should_not : :should
page.send(expectation, have_css(selector))
end
Here is the step definition for Webrat:
Then /^I should (not )?see an element "([^"]*)"$/ do |negate...
Bash Cheat Sheet (standard Emacs mode)
-
Ctrl + R Search commands you entered previously. Press Ctrl + R again to search further back, Ctrl + Shift + R searches forward again.
-
Ctrl + W Deletes from the cursor position to the left.
-
Ctrl + _ Undo. Yes, this also works with a German keyboard layout.
-
Ctrl + L Clear screen.
-
Ctrl + D _Close shell. (EOT, just like in many other shells.) Note: if you dove into another shell (e.g. with
sudo su username
) you will close it and return to ...
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.