A simpler default controller implementation
Rails has always included a scaffold
script that generates a default controller implementation for you. Unfortunately that generated controller is unnecessarily verbose.
When we take over Rails projects from other teams, we often find that controllers are the unloved child, where annoying glue code has been paved over and over again, negotiating between request and model using implicit and convoluted protocols.
We prefer a different approach. We believe that among all the classes in a Rails project, controllers are some of the hardest to...
Fix "An error occurred while installing debugger-linecache" with Ruby 1.9.3
You're better off using debugger-ruby_core_source
:
gem install debugger-ruby_core_source
If you can't do this, try the following.
Here is how to fix the following error when installing the debugger
gem fails:
Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension
Note: The following example is for a project using Ruby 1.9.3-p448 -- adjust accordingly for your project.
-
Fetch the source for your Ruby version, if you do not yet have it:
rvm fetch ruby-1.9.3-p448
-
Install t...
How to not repeat yourself in Cucumber scenarios
It is good programming practice to Don't Repeat Yourself (or DRY). In Ruby on Rails we keep our code DRY by sharing behavior by using inheritance, modules, traits or partials.
When you reuse behavior you want to reuse tests as well. You are probably already reusing examples in unit tests. Unfortunately it is much harder to reuse code when writing integration tests with Cucumber, where you need to...
Geordi: Choose your firefox version for cuc
Geordi 0.16+ supports running selenium tests with project-specific firefox versions.
Just update the gem. It will still default to using the old 5.0.1 firefox. If you want another one, add a file .firefox-version
to your project, containing your preferred version.
geordi cucumber
will prompt (and guide) you to install the given version. You can delete any old installation sitting in /opt/firefox-for-selenium
if you have one.
VCR: Alternative way of mocking remote APIs
If you need to test interaction with a remote API, check out the VCR gem as an alternative to Webmock or stubbing hell.
The idea behind VCR is that is performs real HTTP requests and logs the interaction in a .yml file. When you run the test again, requests and responses are stubbed from the log and the test can run offline.
It's a great way to mock network requests to an external service without going through the pain of log...
Implementing social media "like" buttons: Everything you never wanted to know
So you client has asked you to implement a row of buttons to like the URL on Facebook, Twitter and Google+. Here are some things you should know about this.
0. Security considerations
Each "like" button is implemented by including a Javascript on your site. This means you are running fucking remote code on your page. You are giving Facebook, Twitter and Google+ full permission to e. g. copy user cookies. Check with your client if she is cool with that. Also note that if you're site is suggesting security by operating under HTTPS ...
Enable CSRF protection in Javascript tests
You might not know that Rails disables CSRF protection in tests. This means that if you accidentally forget to send the CSRF token for non-GET requests, your tests will be green even though your application is completely broken (a failed CSRF check usually logs out the user). Rails probably does this because CSRF protection sort of requires Javascript.
You want to enable CSRF protection in Cucumber scenarios that can speak Javascript. To do so, copy the a...
Rails 3/4: How to add routes for specs only
If you want to have routes that are only available in tests (e.g. for testing obscure redirects), you can use the with_routing
helper -- but that one destroys existing routes which may break a specs that require them to work.
To keep both "regular" and test routes, do this:
class MyApplicationController < ActionController::Base
def show
render text: 'Welcome to my application'
end
end
test_routes = Proc.new do
get '/my_application' => 'my_application#show'
end
Rails.application.routes.ev...
How to change the locale of a PostgreSQL cluster
There may be reasons to change the locale of your Postgres cluster. A popular one is your development system's locale being used by default (which may be annoying). Here is how to do that.
Beware: By following the steps below, you will drop and recreate your cluster. You will lose all data (including roles). Instructions below include a procedure for dumping and restoring all cluster data (including roles). While it worked at the time of writing, you should have extra backup strategies for a production database.
- Find the cluster you...
Disable text-transforms in Selenium tests
Using text-transform: uppercase
- especially on form labels - can cause you serious headaches in Selenium tests. Sometimes the web driver will see the uppercase text, sometimes it won't, and umlauts will be a problem as well.
Simply disable it in tests, by
-
adding a body class for tests
%body{'data-environment' => Rails.env}
-
overriding the transforms
[data-environment="test"] * text-transform: none !important
Outlook deletes iCalendar ICS eMails and moves them to trash folder
We sometimes send calender data or tasks using iCalendar (ICS) via eMail as specified in RFC 5545.
Recently, a customer noticed that Outlook automatically moved eMails containing such ICS data to deleted items folder and shows the events as tentative on calendar.
This problem is reported on TechNet, for example.
It ...
Custom RSpec matcher for allowed values (or assignable_values)
In contrast to RSpec's included allow_value
matcher, the attached matcher will also work on associations, which makes it ideal for testing assignable_values
.
Usage example
describe Unit do
describe '#building' do
it 'should only allow buildings that a user has access to' do
building = build(:building)
other_building = build(:building)
unauthorized_building = build(:building)
power = Power.new(build(:user))
Power.with_power(power) do
expect(power).to receive(:buildings).at_least...
Capybara: Trigger requests with custom request method
Preface: Normally, you would not need this in integrations tests (probably that's why it is so hard to achieve), because it is no actual "integration testing". If you use this step, know what you are doing.
Destroying a record with Capybara is not as easy as calling visit user_path(user, method: :delete)
, because RackTest's visit
can only perform GET requests.
With this step you can destroy a records using either Selenium or RackTest. Ex...
Raise when there's a I18n translation missing
The translation method translate
and its alias t
have bang brothers: translate!
and t!
. They will raise I18n::MissingTranslationData
on a missing translation instead of printing a string like translation missing: de.custom.failure
.
To turn on raising globally, you need to replace the default exception handler. The attached initializer makes I18n just raise any exception (in a development or test environment).
Font sizing with rem - Snook.ca
CSS3 comes with new unit rem
. It works like em
but it is always relative to the <html>
element instead of the parent element.
rem
units are supported by all browsers and IE9+.
Testing shared traits or modules without repeating yourself
When two classes implement the same behavior (methods, callbacks, etc.), you should extract that behavior into a trait or module. This card describes how to test that extracted behavior without repeating yourself.
Note that the examples below use Modularity traits to extract shared behavior. This is simply because we like to do it that way at makandra. The same techniques apply for modules and overriding self.included
.
Example
---...
RSpec: Where to put custom matchers and other support code
Custom matchers are a useful RSpec feature which you can use to DRY up repetitive expectations in your specs. Unfortunately the default directory structure generated by rspec-rails
has no obvious place to put custom matchers or other support code.
I recommend storing them like this:
spec/support/database_cleaner.rb
spec/support/devise.rb
spec/support/factory_bot.rb
spec/support/vcr.rb
spec/support/matchers/be_allowed_access.rb
s...
RSpec: Where to put shared example groups
Shared example groups are a useful RSpec feature. Unfortunately the default directory structure generated by rspec-rails
has no obvious place to put them.
I recommend storing them like this:
spec/models/shared_examples/foo.rb
spec/models/shared_examples/bar.rb
spec/models/shared_examples/baz.rb
spec/controllers/shared_examples/foo.rb
spec/controllers/shared_examples/bar.rb
spec/controllers/shared_examples/baz.rb
To ma...
Render a view from a model in Rails
In Rails 5 you can say:
ApplicationController.render(
:template => 'users/index',
:layout => 'my_layout',
:assigns => { users: @users }
)
If a Request Environment is needed you can set attributes default attributes or initialize a new renderer in an explicit way (e.g. if you want to use users_url
in the template):
ApplicationController.renderer.defaults # =>
{
http_host: 'example.org',
https: false,
...
}
...
How to use the Capistrano 2 shell to execute commands on servers
Capistrano 2 brings the shell
command which allows you to run commands on your deployment targets.
There is also invoke
to run a command directly from your terminal.
Both commands allow running Capistrano tasks or shell commands, and scope to individual machines or machine roles.
Unfortunately Capistrano 3 does not include these commands any more.
cap shell
Basics
First of all, spawn a Capistrano shell (we're using the multistage
extension here):
$ cap staging shell
In your "cap" shell you can now run Capistrano ta...
Rails: Disable options of a select field
Simply give the select
helper an option :disabled
, passing either a single value or an array. You need to specify the option's value
, not its text.
= form.select :country, Address.countries_for_select, :include_blank => true, :disabled => ['disabled-value1', 'disabled-value-2']
Also see Cucumber: Check if a select field contains a disabled option on how to test this.
Automated "git bisect" will make your day
So you're hunting down a regression (or just a bug) and want to use git bisect
to find out when it was introduced? Smart kid.
If you have a shell command ready to reveal if your current state is good or bad, you can have git do most of the work for you.
Using git bisect run <your command>
you can tell git that your command will reveal the issue; git on the other hand will use the return value of that call to decide if the state is good or bad.
...
Consul 0.9 lets you optimize records checks
Consul 0.9 comes with many new features to optimize powers that only check access to a given record. e.g. Power.current.post?(Post.last)
. See below for details.
Powers that only check a given object
Sometimes it is not convenient to define powers as a collection. Sometimes you only want to store a method that
checks whether a given object is accessible.
To do so, simply define a power that ends in a question mark:
class Power
...
power :upd...
Cryptic Ruby Global Variables and Their Meanings
The linked page lists and explains global Ruby "dollar" variables, such as:
-
$:
(load path) -
$*
(ARGV
) -
$?
(Last exit status) -
$$
(PID) -
$~
(MatchData
from last successful match) - ...and many more you'll need when reading weird code.
Regex
-
$~
(lastMatchData
) -
$1 $2 $3 $4
(match groups from the last pattern match) -
$&
(last matched string) -
$+
(last match group) - `$`` (the string before the last match)
-
$'
(the string after the last match
See [this extensive list of variables](http://www.tu...