How to configure file watchers in RubyMine
Installation
You need to install the official plugin, it is not bundled with RubyMine by default.
Example: Setup a watcher to verify rubocop integrity
First, open Settings -> Tools -> File Watchers. Then, configure rubocop to check every change to the VCS:
Note that the "program" argument must be part of your $PATH
. I worked around this constraint by using b
as a shim for bundle exec
.
Resources
- [File watchers documen...
Convert curl commands to ruby code
curl-to-ruby is a handy tool that converts your curl
command to ruby code that uses the Net::HTTP library.
Example
curl -X POST -d
"grant_type=password&email=email&password=password"
localhost:3000/oauth/token
will output to:
require 'net/http'
require 'uri'
uri = URI.parse("http://localhost:3000/oauth/token")
request = Net::HTTP::Post.new(uri)
request.set_form_data(
"email" => "email",
"grant_type" => "password",
"password" => "password",
)
req_options =...
Using ffmpeg as a HLS streaming server
A practical and detailed walk-through tutorial on using ffmpeg for live-streaming HLS, filled with real-world examples.
- Using FFmpeg as a HLS streaming server (Part 1) – HLS Basics
- Using FFmpeg as a HLS streaming server (Part 2) – Enhanced HLS Segmentation
- Using FFmpeg as a HLS streaming server (Part 3) – Multiple Bitrates
- Using FFmpeg as a HLS streaming server (Part 4) – Multiple Video Resolutions
- Using FFmpeg as a HLS streaming server (Part 5) – Folder Structure
- Using FFmpeg as a HLS streaming server (Part 6) – Independent Seg...
Ruby: Comparing a string or regex with another string
In Rubocop you might notice the cop Style/CaseEquality
for e.g. this example:
def foo(expected, actual)
expected === actual
end
In case expected
is a Regex, it suggests to change it to the following pattern:
def foo(expected, actual)
expected.match?(actual)
end
In case expected
is a Regex or a String, you need to keep ===
. Otherwise the actual
expression is always converted to a regular expression.
# For expected === actual
foo('Test(s)', 'Test(s)') #=> true
# For expected.match?(actual)
foo('Test(...
Passive event listeners may speed up your scroll and touch events
Scroll and touch event listeners tend to be computationally expensive as they are triggered very often. Every time the event is fired, the browser needs to wait for the event to be processed before continuing - the event could prevent the default behavior. Luckily there is a concept called passive event listeners which is supported by all modern browsers.
Below are the key parts quoted from WICG's explainer on passive event listeners. See [this demo video](https://www.youtube.com/watch?v=NPM6172...
Ruby: A short summary of available hooks in Cucumber
Here is a short summary of Cucumber hooks in Ruby taken from https://github.com/cucumber/cucumber-ruby. Note that the BeforeStep
is currently not existing in the Ruby implementation of Cucumber.
Before
hooks run before the first step of each scenario.
Before do |scenario|
...
end
After
hooks run after the last step of each scenario, even when the step result is failed
, undefined
, pending
or skipped
.
...
How to negate scope conditions in Rails
Sometimes you want to find the inverse of an ActiveRecord scope. Depending on what you want to achieve, this is quite easy with Rails 7, and a bit more complicated with Rails 6 and below, or when the inverse scope may contain NULL values. [1]
There are two different ways of "inverting a scope":
As an example, consider the following model.
class User < ApplicationRecord
scope :admins, -> { where(role: ['admin', 'superuser']) }
# ...
end
Mathematical NOT
You know this one from basic set theory. It proces the "complementa...
Manage Linux services on the command line (Ubuntu)
Ubuntu 18.04 uses systemd
to manage services.
There are basically two commands for listing all services and manipulating the state of a certain service: service
and systemctl
:
-
service
manages System V init scripts -
systemctl
controls the state of the systemd system and service manager. It is backwards compatible to System V and includes the System V services
Therefore I prefer to use systemctl
.
See which services are there
>systemctl list-units -a --type=service
UNIT LOAD ...
Migrate gem tests from Travis CI to Github Actions with gemika
We currently test most of our gems on Travis CI, but want to migrate those tests to Github Actions. This is a step-by-step guide on how to do this.
Note that this guide requires the gem to use gemika.
- Go to a new "ci" branch:
git checkout -b ci
- Update gemika to version >= 0.5.0 in all your Gemfiles.
- Have gemika generate a Github Actions workflow definition by running
mkdir -p .github/workflows; bundle exec rake gemika:generate_github_actions_workflow > .github/workf...
Debugging SPF records
While debugging a SPF record I found spf-record.de to be very helpful.
- it lists all IPs that are covered by the SPF record
- shows syntax errors
- helps you debugging errors like DNS lookup limit reached
- it also lets you test a new SPF strings before applying it. This can save you time as you don't have to loop with operations
Also the advanced check at vamsoft.com has a very good interface to test new SPF policies.
PostgreSQL: Importing dumps created with newer versions
When loading a database dump created with pg_dump
into your database, you might run into an error like
pg_restore: error: unsupported version (1.15) in file header
This is because your local pg_restore
version is too old to match the format created by pg_dump
. The version of the PostgreSQL server doesn't matter here.
For example, the official Ubuntu 20.04 sources include only PostgreSQL 12, so your pg_restore
version will also be v12. Ubuntu 22.04 includes version 14 in its sources.
Both seem to be incompatible with dumps ...
Rails: How to restore a postgres dump from the past
It sometimes happen that a database dump, that would want to insert into your development database, does not match the current schema of the database. This often happens when you have an old dump, but your current setup is up to date with the the master.
Hint: In most cases it is sufficient to delete and recreate the local database in order to import the dump. If any problems occur, proceed as follows:
1. Figure out the original migration status of the dumpfile
- Convert your dump to plaintext: `pg_restore -f some.dump > some.dump....
How to implement simple queue limiting/throttling for Sidekiq
The sidekiq-rate-limiter gem allows rate-limiting Sidekiq jobs and works like a charm. However, it needs to be integrated on a per-worker basis.
If you want to limit a whole queue instead, and if your requirements are simple enough, you can do it via a Sidekiq middleware yourself.
Here is an example that limits concurrency of the "mailers" queue to 1. It uses a database mutex via the [with_advisory_lock](https://github.com/ClosureTree/wit...
VCR and the webdrivers gem
If you're using the webdrivers gem and VCR together, depending on your configuration, VCR will yell at you regulary.
The webdrivers gem tries to update your webdrivers on your local machine. To do so, it checks the internet for newer versions, firing an HTTP-request to e.g. https://chromedriver.storage.googleapis.com
You can "fix" this in multiple ways:
-
Update your drivers on your machine with
RAILS_ENV=test rake webdrivers:chromedriver:update
-
Ignore the driver update-URL in your ...
Simple form examples with bootstrap
Good reference how to build bootstrap forms with simple_form.
How to include Sidekiq job IDs in Rails logs
When logging in Rails, you can use the log_tags
configuration option to add extra information to each line, like :request_id
or :subdomain
. However, those are only valid inside a request context and have no effect when your application is logging from inside a Sidekiq process.
This includes custom as well as any framework logs, like query logging from ActiveRecord.
Since Sidekiq Workers run inside threads of a single process, running multiple jobs in...
How to generate GIDs from an ActiveRecord scope
ActiveRecord provides the ids
method to pluck ids from a scope, but what if you need to pluck Global IDs?
While you could just call map(&:to_global_id)
on your scope, this approach would instantiate each record just to do that. When you have many records, this will at the very least be slow.
Here is a method that does it for you efficiently. It respects Single Table Inheritance (STI).
Put it in your project's ApplicationRecord
to make it available on all models.
class ApplicationRecord
...
Ruby: How to determine the absolute path relative to a file
If you want to get the path of a file relative to another, you can use the expand_path
method with either the constant __FILE__
or the method __dir__
. Read this card for more information about __FILE__
and __dir__
.
Example
Structure:
.
├── bin
│ ├── format_changelog
├── CHANGELOG.md
bin/format_changelog
:
#!/usr/bin/env ruby
changelog_path = ? # How to get the path to ../CHANGELOG.md independent of the working dir of the caller
changelog = File.read(changelog_path)
# ... further actions...
Chrome: Using browser notifications
Development
Google Chrome disables Notification
s for insecure origins (i.e. those using HTTP). Only http://localhost
is considered secure.
If you need to use browser notifications on other origins, you can set a flag: chrome://flags/#unsafely-treat-insecure-origin-as-secure. Enable the flag and add your origins. Remember that "origin" refers to the combination of protocol+hostname+port, e.g. "http://example.com:8088".
CSS variables aka CSS Custom Properties
CSS variables are very different from preprocessor variables. While preprocessors use variables to compile a static piece of CSS, CSS custom properties are a reactive (i.e. live) part of the styles. Think of them like usual CSS properties that cascade, but have:
- A special syntax: CSS variables always start with a double-dash (
--color
) - No inherent meaning: Defining a CSS variable will not change any styles in itself
- A special functionality: CSS variables can be used within the values of other properties, including CSS variables...
Controlling issue grouping in Sentry
When you use Sentry to monitor exceptions, an important feature is Sentry's error grouping mechanism. It will aggregate similar error "events" into one issue, so you can track and monitor it more easily. Grouping is especially important when you try to silence certain errors.
It is worth understanding how Sentry's grouping mechanism works.
The default grouping mechanism
The exact algorithm has changed over time, and Sentry will keep using the algorithm t...
Clean your Rails routes: grouping
In Ruby on Rails, all the routes of a given application can be found within the config/routes.rb file.
You add more and more routes in this file as your project grows.The problem here is that this file potentially becomes very complicated to manage over the time.
That’s why it’s important to find a way to order and maintain your routes.
See: Clean your Rails routes: grouping
Sometimes the routes.rb
grows very fast and each line adds mo...
Ruby: Appending lines to a file in sync
When writing some logs to a file, that don't use Ruby's logger utility, it is often useful to sync them. So other process can read the output just in time.
Example with enabled sync
log_path = '/tmp/some_log.log'
log_file = File.open(log_path, 'a+')
log_file.sync = true
log_file.puts('Some log message')
File.read(log_path) #=> "Some log message\n"
log_file.puts('Some other message')
File.read(log_path) #=> "Some log message\nSome other message\n"
Example ...
Parallel cucumber: How to pass in cucumber arguments
Here is an example with the --tags
option. You need to wrap them inside --cucumber-options
option of parallel_cucumber
.
DISPLAY=:17 bundle exec parallel_cucumber --cucumber-options '--tags @solo' features
See more details in the docs.