Rails: Validations of Dates, Numerics and Strings with ComparisonValidator
tl;dr
Since Rails
7+
you can useComparisonValidator
for validations likegreater_than
,less_than
, etc. on dates, numerics or strings.
Example
We have a model for booking a trip. This model has mandatory attributes to enforce dates for the start and the end.
# == Schema Information
#
# start_date :date
# end_date :date
# ...
class TripBooking < ApplicationRecord
validates :start_date, presence: true
validates :end_date, presence: true
end
These validations are enough. We also want to ensure, th...
How to emulate simple classes with plain JavaScript
If you want a class-like construct in JavaScript, you can use the module pattern below. The module pattern gives you basic class concepts like a constructor, private state, public methods.
Since the module pattern only uses basic JavaScript, your code will run in any browser. You don't need CoffeeScript or an ES6 transpiler like Babel.
A cosmetic benefit is that the module pattern works without the use of this
or prototypes.
Example
Here is an example for a Ruby class that we want to translate into Javascript using the module patter...
Whitelist Carrierwave attributes correctly
Say you have a User
with a Carrierwave attribute #avatar
:
class User < ActiveRecord::Base
mount_uploader :avatar, AvatarUploader
end
When whitelisting the avatar
field in the controller, you might do this:
params[:user].permit(:avatar)
But you probably want this:
params[:user].permit(:avatar, :avatar_cache, :remove_avatar)
In this example:
-
:avatar_cache
allows a newly upload image to persist through form roundtrips in the case of validation errors (something that isn't possibl...
Git: Switch
tl;dr
git checkout
is the swiss army of git commands. If you prefer a semantically more meaningful command for branch related tasks, usegit switch
instead.You can use
git switch
since git 2.23.
Switch Branch
git branch
# * master
# feature-branch
git switch feature-branch
git branch
# master
# * feature-branch
git switch -
git branch
# * master
# feature-branch
Info
For this use case you can of course also use
git checkout
.
Switch on a Remote Branch
git branch -a
# * m...
Exploring the disk usage with ncdu
Ncdu is a disk usage analyzer with an ncurses interface. It is designed to find space hogs on a remote server where you don’t have an entire graphical setup available, but it is a useful tool even on regular desktop systems. Ncdu aims to be fast, simple and easy to use, and should be able to run in any minimal POSIX-like environment with ncurses installed.
Alternatives
du -hs * | sort -h
- Disk Usages Analyser
How to find out what is running on a port on a remote machine
By convention, common protocols use a defined port, like 80 for HTTP or 443 for HTTPS.
You can use nmap
to find out what service is running behind a given port, and most often see some details about it. This can be helpful if servers don't offer the services you expect for some ports. If you'd like to see what ports are listing on your local machine, you might want to use netstat
instead of nmap
.
Note that nmap's service discovery may trigger several requests.
Example
When using nmap, adding the -A
switch ...
Organize large I18n dictionary files in Ruby on Rails
If you're suffering from a huge de.yml
or similiar file, cry no more. Rails lets you freely organize your dictionary files in config/locales
.
My organization works like this:
-
config/locales/rails.de.yml
modified Rails boilerplate -
config/locales/faker.de.yml
modified Faker boilerplate -
config/locales/models.de.yml
model names, attribute names, assignable_value labels - `config/locales/views.de.y...
ActiveRecord: Named bindings in conditions
In Active Record you can use named bindings in where
-conditions. This helps you to make your code more readable and reduces repetitions in the binding list.
Example without named bindings
User.where(
'name = ? OR email ?',
params[:query],
params[:query]
)
Example with named bindings
User.where(
'name = :query OR email :query',
query: params[:query]
)
Careful when using Time objects for generating ETags
You can use ETags to allow clients to use cached responses, if your application would send the same contents as before.
Besides what "actually" defines your response's contents, your application probably also considers "global" conditions, like which user is signed in:
class ApplicationController < ActionController::Base
etag { current_user&.id }
etag { current_user&.updated_at }
end
Under the hood, Rails generates an ETag header value like W/"f14ce3710a2a3187802cadc7e0c8ea99"
. In doing so, all objects from that etagge...
Use capybara and not rspec matchers
One rule of thumb I try to follow in capybara tests is using capybara matchers and not plain rspec matchers.
One example:
visit(some_page)
text_field = find('.textfield')
expect(text_field['value']).to match /pattern/
This can work, but is too brittle and flaky. match
will not retry or synchronize the value of text_field
.
The equivalent code with a capybara matcher:
visit(some_page)
expect(page).to have_field('.textfield', with: /pattern/)
have_field
will retry for and synchronize the text_field.
Git: Restore
tl;dr
git checkout
is the swiss army of git commands. If you prefer a semantically more meaningful command for restoring tasks, usegit restore
instead.With this command you can ...
- ... do unstaging -
git restore --staged
- ... discard staged changes -
git restore --staged --worktree
- ... discard unstaged changes -
git restore
- ... restore deleted files -
git restore
- ... restore historic versions -
git restore --source
- ... recreate merge conflicts -
git restore --merge
- ... specifiy...
Checklist: Using Carrierwave in a Rails project
This checklist should help you to check edge cases that are not part of the default Carrierwave configuration.
- Check Default Configuration and Suggested Changes
- Use secret URLs.
- Check if you need expiring public URLs.
- Check if you need an optimized cache
- Use a [nested directory structure](https://makandracards.com/m...
You can implement basic object-fit behavior with background images
So you want to use object-fit
, but you also need to support Internet Explorer.
One option is to use lazysizes as a kinda-polyfill. Another option is to implement the requirement with background-size: contain
, and background-size: cover
, which is supported in IE9+.
E.g. to make an image cover a 100x100 px² area, cropping the image when nece...
How to use pessimistic row locks with ActiveRecord
When requests arrive at the application servers simultaneously, weird things can happen. Sometimes, this can also happen if a user double-clicks on a button, for example.
This often leads to problems, as two object instances are modified in parallel maybe by different code and one of the requests writes the results to the database.
In case you want to make sure that only one of the requests "wins", i.e. one of the requests is fully executed and completed while the other one at least has to wait for the first request to be completed, you ha...
Detect the current Rails environment from JavaScript or CSS
Detecting if a Javascript is running under Selenium WebDriver is super-painful. It's much easier to detect the current Rails environment instead.
You might be better of checking against the name of the current Rails environment. To do this, store the environment name in a data-environment
of your <html>
. E.g., in your application layout:
<html data-environment=<%= Rails.env %>>
Now you can say in a pi...
In MySQL, a zero number equals any string
In MySQL comparing zero to a string 0 = "any string"
is always true!
So when you want to compare a string with a value of an integer column, you have to cast your integer value into a string like follows:
SELECT * from posts WHERE CAST(posts.comments_count AS CHAR) = '200'
Of course this is usually not what you want to use for selecting your data as this might cause some expensive database operations. No indexes can be used and a full table scan will always be triggered.
If possible, cast the compared value in your application to...
A community-curated list of flexbox issues and cross-browser workarounds for them
This repository is a community-curated list of flexbox issues and cross-browser workarounds for them. The goal is that if you're building a website using flexbox and something isn't working as you'd expect, you can find the solution here.
As the spec continues to evolve and vendors nail down their implementations, this repo will be updated with newly discovered issues and remove old issues as they're fixed or become obsolete. If you discover a bug that's not listed here, please report it so everyone else can benefit.
How to fix "Exit with code 1 due to network error: ProtocolUnknownError" with wkhtmltopdf
New versions of wkhtmltopdf dissallow file://
URLs by default. You can allow them by passing --enable-local-file-access
.
If you are using PDFKit, set the option
PDFKit.configure do |config|
config.default_options = {
enable_local_file_access: true,
}
end
This will be necessary in many setups to allow wkhtmltopdf to fetch assets (such as stylesheets) from the filesystem.
Note on security
Allowing this poses some risk when you render user input, since it might be feasible to include data from the local filesyste...
Git commands to discard local changes
Use case
You have uncommited changes (you can always check by using git status
), which you want to discard.
Context
Now there are several options to discard these depending on your exact situation.
The headlines will differentiate the cases whether the files are staged or unstaged.
- Staged and unstaged changes
- [Staged changes](https://makandracards.com/makandra/516559-git-commands-to-discard-local-changes#s...
RubyMine: Find and Replace with Regex (Capture Groups and Backreferences)
tl;dr
In RubyMine you can use find and replace with capture groups
(.*?)
and backreferences$1
(if you have several groups:$[Capture-Group ID]
).
Named captures(?<text>.*)
are also supported.
Examples
Replace double quotes with single quotes
If you want to replace double quotes with single quotes, replacing every "
with a '
is prone to errors. Regular expressions can help you out here.
- Open find and replace
- Activate the regex mode (click on the
.*
icon next to the "find" field). - Fill in f...
SEO: The subtle differences of robots.txt disallow vs meta robots no-index
The robots.txt file and <meta name="robots">
HTML tag can be used to control the behavior of search engine crawlers. Both have different effects.
robots.txt
Marking a URL path as "disallowed" in robots.txt tells crawlers to not access that path.
robots.txt is not a guarantee for exclusion from search engine results.
A "disallowed" URL might be known from an external link, and can still be displayed for a matching search.
Example: even if/admin
is disallowed in robots.txt, `/admin/som...
Do not use "flex: 1" or "flex-basis: 0" inside "flex-direction: column" when you need to support IE11
Flexbox is awesome. Most of it even works in IE11, but flex: 1
won't work reliably in Internet Explorer.
This it because implicitly sets flex-basis: 0
which IE fails to support properly.
Example
Consider the following HTML and CSS.
<div class="container">
<div class="child">
foo
</div>
<div class="bar">
bar
</div>
</div>
.container {
display: flex;
flex-direction: column;
}
.child {
flex: 1;
}
See it in action at Plunker.
Background
...
Rails: Overwriting default accessors
All columns of a model's database table are automagically available through accessors on the Active Record object.
When you need to specialize this behavior, you may override the default accessors (using the same name as the attribute) and simply call the original implementation with a modified value. Example:
class Poet < ApplicationRecord
def name=(value)
super(value.strip)
end
end
Note that you can also avoid the original setter and directly read/write from/to the instance's attribute storage. However this is dis...
Project management best practices: Standup
If the project team consists of at least 2 members, do a daily standup. It should not take much longer than 15 minutes.
Format
Tell everyone else
- what you did yesterday
- what you intend to do today
- where you might need help or other input
- if there are new developments everyone needs to know about
A "still working on X, will probably be done today" is totally fine. No need to tell a long story.
If you are out of work, find a new story with the others.
If there are new stories in the backlog, look at them and
- make sure ev...