Run a script on the server
You have to specify the environment with -e env_name or RAILS_ENV=env_name if you want to run a script on the server.
at Rails 2 it's script/runner
bundle exec script/runner -e env_name path/to/script.rb argument1 argument2 ...
at Rails 3 it's rails runner
RAILS_ENV=env_name bundle exec rails runner path/to/script.rb argument1 argument2 ...
ActionMailer: How to send a test mail directly from the console
If your rails application is unable to send mails, it might be useful to debug your settings using the rails console. Here is a snippet that shows the current settings and lets you send a test mail directly from the console:
mailer = ActionMailer::Base.new
# check settings:
mailer.delivery_method # -> :smtp
mailer.smtp_settings # -> { address: "localhost", port: 25, domain: "localhost.localdomain", user_name: nil, password: nil, authentication: nil, enable_starttls_auto: true }
# send mail:
mailer.mail(from: 'sender@example.com', ...
Retrieve the SQL query a scope would produce in ActiveRecord
Rails 3
User.active.to_sql
Rails 2
Use either the Edge Rider or fake_arel gem to get #to_sql backported to Rails 2.
If you don't want to use a gem for this, you can do this with vanilla Rails 2:
User.active.construct_finder_sql({})
How to fix gsub on SafeBuffer objects
If you have an html_safe string, you won't be able to call gsub with a block and match reference variables like $1. They will be nil inside the block where you define replacements (as you already know).
This issue applies to both Rails 2 (with rails_xss) as well as Rails 3 applications.
Here is a fix to SafeBuffer#gsub. Note that it will only fix the $1 behavior, not give you a safe string in the end (see below).
Example
def test(input)...
Geordi 1.3 released
Changes:
- Geordi is now (partially) tested with Cucumber. Yay!
- geordi cucumber supports a new @solo tag. Scenarios tagged with
@solowill be excluded from parallel runs, and run sequentially in a second run - Support for Capistrano 2 AND 3 (will deploy without
:migrationson Capistrano 3) - Now requires a
.firefox-versionfile to set up a test firefox. By default now uses the system Firefox/a test Chrome/whatever and doesn't print warnings any more. -
geordi deploy --no-migrations(aliased-M): Deploy with `cap ...
Caution: `.includes` can make `.ids` non-unique.
This can happen with a very simple model:
class Note
has_many :attachments
end
Everything looks normal:
Note.all.to_a.size # => 8
Note.all.ids.size # => 8
Then .includes leads to weird results:
Note.all.includes(:attachments).to_a.size # => 8
Note.all.includes(:attachments).ids.size # => 12
If a note has 5 attachments, its id will be included 5 times.
With .preload it works as expected:
Note.all.preload(:attachments).to_a.size # => 8
Note.all.preload(:attachments).ids.size # => 8
Note
I crea...
Copy to clipboard without flash (clipboard.js)
We used zeroclipboard.js in some of our projects but now we switched to clipboard.js because it does not rely on flash. Flash support of the major browsers has ended.
Some more advantages of clipboard.js:
- it consists only of a single javascript file, so it does not trigger additional requests with rails
- it automagically provides user feedback by selecting the text it has copied
- it provides callbacks for success and error which make it easier to add custom behaviour after copying to the clipboar...
Linux Performance Analysis in 60,000 Milliseconds
You login to a Linux server with a performance issue: what do you check in the first minute?
uptime
dmesg | tail
vmstat 1
mpstat -P ALL 1
pidstat 1
iostat -xz 1
free -m
sar -n DEV 1
sar -n TCP,ETCP 1
top
Also see:
Render Sass stylesheets dynamically
If - for whatever reason - you have to render stylesheets dynamically, the following snippet might be of help. It emulates what "sprockets" would to when precompiling your assets, and give your stylesheets access to all the regular bells and whistles (like asset_path, proper @imports etc):
class DynamicStylesheetsController < ApplicationController
def show
logical_path = RELATIVE_PATH_TO_YOUR_TEMPLATE
path = File.join(Rails.root, logical_path)
template = Sass::Rails::SassTemplate.new(path)
environment = ...
Test redirects to an external URL with Cucumber/Capybara
When a controller action redirects to an external URL (like http://somehost.com/some/path) you will find that this is hard to test with Cucumber and Capybara:
- A non-Javascript Rack::Test scenario will just ignore the host and try to open
/some/pathin your local application - A Selenium test will actually follow the redirect, which you probably don't want either
There are two workarounds for this. You can use either, or a combination of both.
- Write a controller spec
Controller specs can test if a resp...
Asset Pipeline Basics
The Rails asset pipeline improves delivery of application assets (javascripts, stylesheets, images, fonts). Here are some basic facts about its inner workings.
No magic
Manifests are the handle on your assets:
app/assets/stylesheets/application.css # use via: stylesheet_link_tag 'application'
The asset pipeline only considers files you explicitly require within your manifest files. The most common directives used in manifests are require some/file and require_tree some/directory. Paths may be **relative to the current director...
Designing HTML emails
The 90s are calling: they want their tables back. Unfortunately, you need them all for laying out your HTML emails.
Email client HTML rendering is way more scattered than browser HTML. While you might have a pretty good understanding of what features and patterns you can use to support all major browsers, I doubt anyone masters this craft for HTML email clients.
The only way to ensure your email looks good (acceptable, at least) in all mail clients, is to check it. Litmus is your go-to solution for this (see below). W...
Careful when writing to has_many :through associations
tl;dr: Using has_many associations with a :through option can lead to lost or duplicate records. You should avoid them, or only use them to read records.
Consider this:
class User < ActiveRecord::Base
end
class Party < ActiveRecord::Base
has_many :invitations
has_many :users, through: :invitations, include: :user, order: 'users.name'
end
class Invitation < ActiveRecord::Base
belongs_to :party
belongs_to :user
after_create :send_invite
def send_invite
...
How to fix: Gems are unavailable although they are installed
- If Rails or Rake are complaining about a missing gem that is listed in your
Gemfile.lockand the listed version is properly installed, something is seriously wrong and needs to be fixed. - If you accidently executed
bundle install some_gemalthough you wantedbundle update some_gem
What is wrong
Let's say your Gemfile asks for some-gem which you can see when running gem list but bundle show some-gem just gives you an error:
Could not find gem 'some-gem', in any of the sources
Another indicator: Doing a `...
How to mount a legacy database to migrate data
There are many approaches out there how you can import data from a legacy application to a new application. Here is an approach which opens two database connections and uses active record for the legacy system, too:
1. Add you database information to you config/database.yml.
data_migration:
database: your_application_data_migration
2. Create a separate application record for the data migration, e.g. in app/data_migration/migration_record.rb. You will need to create an app/data_migration.rb class first.
class DataMig...
Nicer alternatives to def_delegator or def_delegators
Delegating methods to other objects is often helpful but the syntax of both def_delegators and def_delegator is a complete mess that makes your code hard to read.
Consider these classes:
class Topic < ActiveRecord::Base
def title
"A title"
end
def category
"Topic category"
end
end
class Post < ActiveRecord::Base
belongs_to :topic
def_delegato...
IRB's multi-line autocomplete and how to disable it
Recent IRB versions include a multi-line autocomplete which may be helpful to novice users but can be distracting.
Cycling through options works by pressing the Tab key (as usual), and for some methods you also get some kind of documentation, though the quality of results is usually not on par with your IDE of choice.
I have found that it also slows down my IRB in some cases, or that pressing the Backspace key does not always reliably remove characters, which I find more annoying than useful.
You may disable multi-line autocomplete by
- ...
New Firefox and gem versions for our Selenium testing environment (Ubuntu 14.04+)
Firefox 5.0.1, which we were using for most Rails 2.3 projects, does not run on Ubuntu 14.04 any more. Here is how to update affected projects.
-
Update (or create)
.firefox-versionwith the content:24.0
If you haven't installed Firefox 24 yet, the next time you run tests with Geordi, it will tell you how to install it. -
On a Rails 2 project:
-
Update your Cucumber-related gems as described in Upgrading Cucumber and Capybara, including
cucumber_spinnerandlaunchy. -
If you...
-
Ruby constant lookup: The good, the bad and the ugly
In Ruby, classes and modules are called constants. This card explains how Ruby resolves the meaning of a constant.
The good
E. g. in the following example, Array could mean either Foo::Array or simply Array:
class Foo
def list
Array.new
end
end
What Ruby does here is to see if the name Array makes sense inside of Foo::, and if that fails, resolves it to ::Array (without a namespace).
The bad
This is relevant for old Ruby versions. Ruby 2.5+ removes top-level constant lookup whi...
Pimp my IRB
Put the attached files into your home directory and enjoy.
.irbrc
- defines
interesting_methods, which is essentially all methods without top-level methods inherited from Object/Module - requires
awesome_print, if present - requires
interactive_editor, if present (basically makes vim available) - loads .irbrc_rails if in Rails (e.g. for the Rails console)
.irbrc_rails
- defines
efind(email), which is a shortcut to find users by email
...
HTML emails with inline stylesheets and webpacker
Many mail clients do not support external style sheets. Some even require all styling inline, which means you'll have to do your styling inline. For Rails applications, you can use Roadie or premailer, which lets you keep your well-structured CSS files and do the inlining for you.
Since Roadie is now in passive maintenance mode, we go with premailer:
Include premailer in your Gemfile:
gem 'premailer-ra...
Fix „command failed: /usr/bin/wkhtmltopdf ...“ using PDFKit middleware
Ubuntu 12.04 LTS x64, Ruby 1.8.7, Rails 2.13, PDFKit 0.5.4, Phusion Passenger Apache 2
I ran into this, when I started using passenger to deal with the Single Thread Issue which caused my webrick to deadlock when an ActionController::RoutingError (No route matches "...") occurred.
These steps brought me a little further
(1) assert dependencies are installed
sudo aptitude install openssl build-essential xorg libssl-dev
(2) only for 64bits OS Run one by one the follo...
How to use Haml in your helpers
You know those helper methods that just render some HTML but look weird because of content_tags all over the place? You could also use Haml instead.
Example
Consider the following helper.
def greeting
message = ''.html_safe
message << 'Welcome to '
message << content_tag(:span, Rails.env, class: 'greeting--location')
content_tag :div, message, class: 'greeting'
end
That looks clumsy and is hard to read.
Wouldn't it be nicer to say something like this?
def greeting
render_haml <<-HAML
...
Split an array into groups
Given group size
If you would like to split a Ruby array into pairs of two, you can use the Rails ActiveSupport method in_groups_of:
>> [1, 2, 3, 4].in_groups_of(2)
=> [[1, 2], [3, 4]]
>> [1, 2, 3, 4, 5].in_groups_of(2)
=> [[1, 2], [3, 4], [5, nil]]
>> [1, 2, 3, 4, 5].in_groups_of(2, 'abc')
=> [[1, 2], [3, 4], [5, 'abc']]
>> [1, 2, 3, 4, 5].in_groups_of(2, false)
=> [[1, 2], [3, 4], [5]]
Given group cou...