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...
RailsPanel chrome extension
Chrome extension that shows all info from your rails log (like parameters, response times, view rendering times, DB requests) inside a chrome panel.
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...
"cannot load such file -- nokogiri/nokogiri" (or any other Gem with native extensions on rvm and Ruby >= 2)
After running bundler / gem install I could not load nokogiri lately. It died with cannot load such file -- nokogiri/nokogiri
.
This is not a problem of the gem but is due to a broken native extensions installation routine.
When installing nokogiri manually and with verbose output by using gem install -V nokogiri -v 1.5.6
, you can see the problem scrolling by when the native extension is built:
/usr/bin//install -c -m 0755 nokogiri.so /home/thomas/.rvm/gems/ruby-2.0.0-p247/gems/nokogiri-1.5.6/lib/home/thomas/.rvm/rubies/ruby-2.0.0-p...
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...
Consul 0.10.0 allows multiple power mappings for nested resources
Consul 0.10.0 now allows multiple power mappings for nested resources.
When using nested resources you probably want two power
checks and method mappings: One for the parent resource, another for the child resource.
Say you have the following routes:
resources :clients do
resources :notes
end
And the following power definitions:
class Power
...
power :clients do
Client.active if si...
Nested controller routes (Rails 2 and 3)
In order to keep the controllers directory tidy, we recently started to namespace controllers. With the :controller
option you can tell Rails which controller to use for a path or resource. For nested resources, Rails will determine the view path from this option, too.
That means the following code in routes.rb
…
resources :users do
resource :profile, controller: 'users/profiles' #[1]
end
… makes Rails expect the following directory structure:
app/
controllers/
users/
profiles_controller.rb
users_control...
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,
...
}
...
exception_notification 4.0.0+ makes it easier to ignore errors, crawlers
The new exception_notification has awesome options like :ignore_crawlers => true
and :ignore_if => lambda { ... }
. These options should be helpful in ensuring every notifications means something actionable (instead of a long log of failures that just scrolls by).
Note that you should not ignore crawlers by default. Ideally, cool URLs never change and always respond with a helpful redirect or similar.
Ignore Errors like this:
# config/initializers/exception_notification.rb
Ex...
MySQL: Careful when using database locks in transactions
We tend to use database transactions as a magic bullet to get rid of all our concurrency problems. When things get really bad, we might even throw in some locking mechanism, but then are usually done with it.
Unfortunately, transactions semantics in databases are actually very complicated, and chances are, your making some incorrect assumptions.
The MySQL innodb engine actually has [four different modes](ht...
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...
Sprites with Compass
Using CSS sprites for background images is a technique for optimizing page load time by combining smaller images into a larger image sprite.
There are ongoing arguments on how useful this still is, as modern browsers become more comfortable to load images in parallel. However, many major websites still use them, for example amazon, [facebook](...
How I Explained REST to my Wife
A great and enjoyable introduction into the concept of the web and about what HTTP was designed for. The original post has been removed for some stupid gender discussion.
Common mistakes when storing file uploads with Rails
1. Saving files to a directory that is not shared between deploys or servers
If you save your uploads to a made up directory like "RAILS_ROOT/uploads"
, this directory goes away after every deploy (since every release gets a new). Also this directory is not shared between multiple application servers, so your uploads are randomly saved to one local filesystem or another. Fixing this afterwards is a lot of fun.
Only two folders are, by default, shared between our application servers and deployments: "RAILS_ROOT/storage"
and `"RAILS...
Upgrading Rails 2 from 2.3.8 through 2.3.18 to Rails LTS
This card shows how to upgrade a Rails 2 application from Rails 2.3.8 through every single patch level up to 2.3.18, and then, hopefully, Rails LTS.
2.3.8 to 2.3.9
This release has many minor changes and fixes to prepare your application for Rails 3.
Step-by-step upgrade instructions:
- Upgrade
rails
gem - Change your
environment.rb
so it saysRAILS_GEM_VERSION = '2.3.9'
- Change your ...
Rails: Send links in emails with the right protocol
ActionMailer per default uses http
as protocol, which enables SSL-stripping. When a logged-in user follows an http
link to your application, it sends the cookies along with it. Although the application redirects the user to https
and from that point has a secure connection to the user, an attacker may overhear that first unsafe request and hijack your session.
Teach ActionMailer to use the right protocol
If your application is behind SSL, turn on using https
application-wide. In your environment file (either global or per environ...
Before you make a merge request: Checklist for common mistakes
Merge requests are often rejected for similar reasons.
To avoid this, before you send a merge request, please confirm that your code ...
- has been reviewed by yourself beforehand
- fulfills every requirement defined as an acceptance criterion
- does not have any log or debugging statements like
console.log(...)
,byebug
etc. - has green tests
- has tests...
Subscribe to Rails security mailing list without Google account
The Ruby on Rails security list archive can be found here: http://groups.google.com/group/rubyonrails-security
You can subscribe to this mailing list without a Google account by pasting this URL into your browser (after replacing the email address obviously).
http://groups.google.com/group/rubyonrails-security/boxsubscribe?email=your.name@example.com
^^^^^^^^^^^^^^^^^^^^^ <- Change this
Duplicate a git repository with all branches and tags
In order to clone a git repository including all branches and tags you need to use two parameters when cloning the old and pushing to the new repository respectively:
git clone --bare http://example.com/old-repo.git
cd old-repo
git push --mirror http://example.com/new-repo.git
Of course, the URLs to your repository might look different depending on the protocol used, username required, etc.
For a user git
using the git protocol, it could be git@example.com:repository-namespace/repository.git
How to find out which type of Spec you are
When you need to find out in which kind of spec you are during run-time, it's definitely possible. It's a lot easier in RSpec 2+.
For example, consider this global before
block where you'd want to run some code for specific specs only:
config.before do
# stuff
that_fancy_method
# more stuff
end
RSpec 2+
If you want to run such a block for a specific type of specs, you can use filters:
config.before do
# stuff
# more stuff
end
config.before :type =...
Browsers will not send a referrer when linking from HTTPS to HTTP
- When your site is on HTTPS and you are linking or redirecting to a HTTP site, the browser will not send a referrer.
- This means the target site will see your traffic as "direct traffic", i.e. they cannot distinguish such hits from a user who directly typed in the URL.
Reasons for this behavior
It's probably because of this RFC:
Clients SHOULD NOT include a Referer header field in a (non-secure) HTTP request if the referring page was transferr...