How to enable SSL in development with Passenger standalone
Here is how to start your Rails application to accept both HTTP and HTTPS in development.
-
gem install passenger
-
Create a self-signed SSL certificate. Store the generated files in config/passenger-standalone-ssl.
-
Create a Passengerfile.json at the project root with this content (or save the attached file):
{ "ssl": true, "ssl_port": 3001, "ssl_certificate": "config/passenger-standalone-ssl/server.crt",
...
List of Helpful RubyMine Shortcuts
Navigation
CTRL + SHIFT + ALT + N
-
Search for any symbol in your application, like CSS classes, Ruby classes, methods, helpers etc.
CTRL + SHIFT + N
-
Search for filename in your application (also dependencies)
CTRL + E
-
Open a list of recently opened files
ALT + POS1
-
Open a the navigation bar as a context menu. Allows you to quickly navigate between files.
CTRL + G
-
Go to line
Actions
CTRL + SHIFT + A
-
...
Capistrano 3 has slightly changed its symlink implementation
In Capistrano 2, directories in shared_children
used to be symlinked to the shared
directory during the finalize_update
task.
# <capistrano>/lib/capistrano/recipes/deploy.rb
_cset :shared_children, %w(public/system log tmp/pids)
# ...
task :finalize_update, :except => { :no_release => true } do
# ...
shared_children.map do |d|
run "ln -s #{shared_path}/#{d.split('/').last} #{latest_release}/#{d}" # <-- symlinks only the last s...
Faster debugging with RubyMine macros
In my RubyMine I have recorded two macros for debugging and linked them to some keyboard shortcuts. Since I believe everyone could benefit from having those I wanted to share this.
The first one simply inserts
binding.pry
and the second one
.tap { |object| binding.pry }
for when you do not have a reference to the object you want to inspect.
In order to record a macro you simply follow the path Edit > Macros > Start Macro Recording
.
Then you simply type binding.pry
or whatever you want to record and stop recor...
Rails 4.1+ automatically detects the :inverse_of an association
Starting from 4.1, Rails automatically detects the inverse of an association, based on heuristics. Unfortunately, it does not seem to notify you when it fails to infer the :inverse_of
, so you are better off to always manually set :inverse_of anyway.
Note that automatic inverse detection only works on
has_many
,has_one
,belongs_to
associations. Extra options on the associations will prevent the association's...
Databases don't order rows unless you tell them so
There is no such thing as a "default order" of rows in database tables.
For instance, when you paginate a result set: When using LIMIT
, it is important to use an ORDER BY
clause that constrains the result rows into a unique order. Otherwise you will get an unpredictable subset of the query's rows. You might be asking for the tenth through twentieth rows, but tenth through twentieth in what ordering? The ordering is unknown, unless you specified ORDER BY
.
In Rails, if you use Record.first
or Record.last
, it will default to orderin...
Exception Notifier: Foreground vs. background sections
Since version 2.6 exception notifier distinguishes between foreground and background sections. The reason is that with background jobs (e.g. methods that are called by a cron job) some variables are not available for exception notifier, e.g. @request
and @kontroller
.
Therefore you can configure foreground and background sections individually. Our default settings are documented in Get notified when your application raises an error.
**W...
Reverse-proxying web applications with Apache 2.4+
Note: Making a reverse proxy with nginx is much more straightforward.
A reverse proxy is a "man in the middle" server that tunnels requests to another server. You can use for things like:
- Expose a local service that you cannot directly reach over the internet
- "Change" the domain or path of a web application by rewriting them on the fly
- Instantly change servers that respond to a name or ...
Upgrading from Capistrano 2 to 3
Capistrano 3 is a major rework of the framework and requires several adjustments to your deploy configuration files. The biggest change is that they moved away from their custom DSL and use Rake
instead. For connecting with and operating on the servers, they bring a new gem SSHKit
which does the heavy lifting. It's SSHKit's DSL that is used anywhere inside the Rake tasks. See #Resources at the bottom for examples.
Step 1: Upgrade guide
For migration from 2 to 3, follow this tutorial: [Capistrano 3 Upgrade Guide](https://semaphorec...
Savon testing: How to expect any message
When using Savon to connect a SOAP API, you may want to use Savon::SpecHelper
to mock requests in your tests as described in their documentation.
When sending a message body, the savon
mock object requires a message to be set, like this:
savon.expects(:action_name).with(message: { user_id: 123 }).returns('<some xml>')
If you want to stub only the returned XML and do not care about request arguments, you can not omit with
as Savon's helper will complain:
savo...
Why you see a GET "/__identify__" request in Capybara tests
You might wonder about this request in your test.log
:
Started GET "/__identify__" for 127.0.0.1 at 2015-04-29 18:00:02 +0100
This is what happens: For drivers like Selenium, Capybara will boot up a Thin or Webrick server in a separate thread. It then makes a GET request to /__identify__
to see if the server is ready to accept requests.
Since you don't have a route that responds to /__identify
, Capybara will wrap your Rails app in...
Using mime types with send_file
When using send_file
(for example for attachments of any kind), make sure your application knows the correct mime types so that all browsers can handle the files. It is much more convenient for users if they can decide to open a file directly instead of having to save it first.
For Rails >= 3.2
Simply put your mime types in config/initializers/mime_types.rb
. send_file
will take care of everything else.
For Rails < 3.2
Put your mime types in config/initializers/mime_types.rb
. Additionally, tell send_file
to use them (for ex...
Capybara: Waiting for pending AJAX requests after a test
When ending a Selenium test Capybara resets the browser state by closing the tab, clearing cookies, localStorage
, etc.
It may be a good idea to wait for all in-flight AJAX requests to finish before ending a scenario:
- You may have client-side JavaScript that freaks out when the tab closure kills their pending requests. If that JavaScript opens an error alert or spams errors to the console, your test may fail after the last step.
- With unlucky timing the server may receive an AJAX request as the browser tab closes, causing a connection ...
Browse Amazon S3 buckets with Ubuntu Linux
There are some frontends available, but they all suck, are no longer maintained or are hard to install.
As a surprisingly comfortable alternative I have found a command line tool s3cmd
:
sudo apt-get install s3cmd
When you run s3cmd
the first time it will ask you for your access key ID and secret access key. This information is cached somewhere so you only need to write them once. To reconfigure later, call s3cmd --configure
.
Once you're done setting up, s3cmd
gives you shell-like commands like s3cmd ls
or `s3cmd del som...
Differences between transactions and locking
Web applications can be used by multiple users at the same time. A typical application server like Passenger has multiple worker processes for a single app. In a distributed deployment setup like we use at makandra you will even have multiple application servers, each with their own worker pool.
This means that your code needs to deal with concurrent data access. The two main tools we use to cope with concurrency are database transactions and distributed locks. These two are not interchangeable. You ca...
Slack integration for deployments via Capistrano
You can hook into Slack when using Capistrano for deployment. The slackistrano gem does most of the heavy lifting for you. Its default messages are unobtrusive and can be adjusted easily.
When deploying, it posts to a Slack channel like this:
How to integrate
Integrating Slackistrano with Capistrano 3 is fairly simple.
- In your Slack, open menu → A...
Getting permanent links to files on Github or Gitlab
Please don't simply copy line number links from Github. The URL usually contains a branch name like master
which will change over time:
https://github.com/makandra/upjs/blob/master/lib/assets/javascripts/up/link.js.coffee#L76
If someone now posts an insertion or deletion to that file into master
your link points to the wrong line!
A better way is to press the Y
key after clicking on a line number. This will transform the URL to another URL that points to the particular commit:
https://github.com/makandra/upjs/blob/b3b14...
Detecting when fonts are loaded via JavaScript
Webfonts are not always available when your JavaScript runs on first page load. Since fonts may affect element sizes, you may want to know when fonts have been loaded to trigger some kind of recalculation.
Vanilla JavaScript / Modern DOM API
In modern browsers (all but IE and legacy Edge) you can use document.fonts
. Use load
to request a font and receive a Promise that will be resolved once the font is available. Example:
document.fonts.load('1rem "Open S...
Ruby: Enumerable#partition
If you want to sort values from an enumerable into two arrays based on whether they match a certain criteria or not, Enumerable#partition
can come in handy.
# Enumerable#partition returns two arrays,
# the first containing the elements of enum
# for which the block evaluates to true,
# the second containing the rest.
(1..6).partition { |v| n.even? } #=> [[2, 4, 6], [1, 3, 5]]
Works well with destructuring assignment, too.
even, odd = (1..6).partition { |n| n.ev...
Sharing cookies across subdomains with Rails 3
To achieve this goal you have to setup the session store like the following example:
MyApp::Application.config.session_store(
:cookie_store,
{
:key => '_myapp_session',
:domain => :all, # :all defaults to da tld length of 1, '.web' has length of 1
:tld_length => 2 # Top Level Domain (tld) length -> '*.myapp.web' has a length of 2
}
)
The invconvenient side effect for local development
… or: Why do I get "Can't verify CSRF token authenticity" even if csrf token is present?
As `:domain => :all...
How to create giant memory leaks in AngularJS (and other client-side JavaScript)
This guide shows how to create an AngularJS application that consumes more and more memory until, eventually, the browser process crashes on your users.
Although this guide has been written for Angular 1 originally, most of the advice is relevant for all client-side JavaScript code.
How to observe memory consumption
To inspect the amount of memory consumed by your Javascripts in Chrome:
- Open an incognito window
- Open the page you want to inspect
- Press
Shift + ESC
to see a list of Chrome processes...
Remove URLs from the Google index
Obviously, you only can do this for your own sites.
You need to authenticate a domain you want to remove content from via Webmaster Tools.
To remove a URL:
- Open Webmaster Tools
- Select the respective site from the list of domains under your control
- Choose "Google Index" from the menu left
- Click "Remove URL"
Rails: Running specific migrations
When running migrations with rake db:migrate
, there's the STEP
and VERSION
parameters that you can pass to nearly all commands.
# Migrate
rake db:migrate
rake db:migrate STEP=2
rake db:migrate VERSION=20080906120000
# Redo
rake db:migrate:redo
rake db:migrate:redo STEP=2
rake db:migrate:redo VERSION=20080906120000
# Rollback (starting from latest migration)
rake db:rollback
rake db:rollback STEP=2
# Run the `down` migration path of a certain migration file
rake db:migrate:down VERSION=20080906120000
Angular + ui-router: Make links work in a new tab
If your angular app is not served on /
, but on a different url (say /admin
), links generated with ui-router will not work when you open them in a new tab.
Fix this by adding this tag in your <head>
:
<base href='/admin#/'>
Helper method:
def base_tag
tag(:base, href: request.path_info + "#/")
end