Ruby has this handy block shortcut map(&:to_i)
for map { |x| x.to_i }
. However, it is limited to argument-less method invocations.
To call a method with an argument, you usually need to use the full block form. A common and annoying case is retrieving values from a list of hashes (imagine using a JSON API):
users = [ { name: 'Dominik', color: 'blue' }, { name: 'Stefan', color: 'red'} ]
names = users.collect do |user|
user[:name]
end
If you're using Rails 5+, this example is covered by Enumerable#pluck
(`users.pluck(:name)...
TL;DR
Append your locale keys with _html to have them marked as
html_safe
and translate them with= t('.text_html')
.
When you're localizing a Rails application, sometimes there is this urge to include a little HTML. Be it some localized link, or a set of <em>
tags, you'd like to have it included in the locale file. Example:
# Locale file
en:
page:
text: 'Please visit our <a href="https://www.corporate.com/en">corporate website</a> to learn more about <em>the corporation</em>.'
# HAML
= t('.text')
# D...
When your application is running on a multi-server setup, application logs are stored per server (unless you choose a centralized logging solution).
Here is a Capistrano task that connects to all servers and prints logs to your terminal like this:
$ cap production app:logs
00:00 app:logs
01 tail -n0 -F /var/www/your-application/shared/log/production.log | while read line; do echo "$(hostname): $line"; done
01 app01-prod: Started GET "/sign_in" for 1.2.3.4 at 2018-04-26 11:28:19 +0200
01 app01-prod: Proc...
When your JavaScript bundle is so massive that you cannot load it all up front, I would recommend to load large libraries from the compilers that need it.
Compilers are also a good place to track whether the library has been loaded before. Note that including same <script>
tag more than once will cause the browser to fetch and execute the script more than once. This can lead to memory leaks or cause duplicate event handlers being registered.
In our work we mostly load all JavaScript up front, since our bundles are small enough. We recent...
You know that you can use jQuery's text()
to get an element's contents without any tags.
If you want to remove only some tags, but keep others, use contents()
and unwrap()
. Here is how.
Consider the following example element.
$container = $('<div><strong>Hello</strong> <em>World</em></div>')
Let's say we want to discard any <em>
tags, but keep their contents.
Simply find
them, then dive into their child nodes via contents
, and use unwrap
replace their ...
For outputting a given String in HTML, you mostly want to replace line breaks with <br>
or <p>
tags.
You can use simple_format
, but it has side effects like keeping some HTML.
If you only care about line breaks, you might be better off using a small, specialized helper method:
def format_linebreaks(text)
safe_text = h(text)
paragraphs = split_paragraphs(safe_text).map(&:html_safe)
html = ''.html_safe
paragraphs.each do |paragraph|
html << content_tag(:p, paragraph)
end
html
end
Full di...
Lets say we have a user
with a contract
whereas contract
is a mounted carrierwave file.
Now we want to send the link to the contract in a mail. For this use case join the root_url
with the public contract path in the mailer view:
URI.join(root_url, @user.contract.url)
link_to('Show contract', URI.join(root_url, @user.contract.url).to_s)
Note: You need to follow [http://guides.rubyonrails.org/action_mailer_basics.html#g...
When you need test images, instead of using services like lorempixel or placehold.it you may generate test images yourself.
Here we build a simple SVG image and wrap it into a data:
URI. All browsers support SVG, and you can easily adjust it yourself.
Simply set it as an image's src
attribute.
Simple solution in modern JavaScript, e.g. for use in the client's browser:
function svgUri(text) {
let svg = `
<svg width="320" height="240" xmlns="http://www.w3...
Rails offers a way to prepend (or append) view paths for the current request. This way, you can make the application use different view templates for just that request.
A use case of this is a different set of view templates that should be used under certain circumstances:
class UsersController < ApplicationController
before_action :prepare_views
def index
# ...
end
private
def prepare_views
if <condition>
prepend_view_path Rails.root.join('app', 'views', 'special')
end
end
...
When you have string contents (e.g. a generated binary stream, or data from a remote source) that you want to store as a file using Carrierwave, here is a simple solution.
While you could write your string to a file and pass that file to Carrierwave, why even bother? You already have your string (or stream).
However, a plain StringIO object will not work for Carrierwave's ActiveRecord integration:
>> Attachment.create!(file: StringIO.new(contents))
TypeError: no implicit conversion of nil into String
This is because Carrierwav...
Form fields can be rendered as noneditable by setting the disabled
or the readonly
attribute. Be aware of the differences:
button
, fieldset
, input
, select
, textarea
, command
, keygen
, optgroup
, option
Browser specific behavior:
If you want to make a screenshot of a website that works well in print or on a high-DPI screen (like Apple Retina displays), here is how you can capture a high-resolution screenshot.
You can do this without an addon:
CTRL +
and CTRL -
so it covers most of the window area. Leave a little padding on the left and right so...When a Rails controller action should handle both HTML and JSON responses, do not use request.xhr?
to decide that. Use respond_to
.
I've too often seen code like this:
def show
# ...
if request.xhr?
render json: @user.as_json
else
# renders default HTML view
end
end
This is just plain wrong. Web browsers often fetch JSON via XHR, but they (should) also send the correct Accept
HTTP header to tell the server the data they expect to receive.
If you say request.xhr?
as a means for "wants JSON" you are ...
TL;DR Use user.update!(remove_avatar: true)
to delete attachments outside of forms. This will have the same behavior as if you were in a form.
As you know, Carrierwave file attachments work by mounting an Uploader
class to an attribute of the model. Though the database field holds the file name as string, calling the attribute will always return the uploader, no matter if a file is attached or not. (Side note: use #present?
on the uploader to check if the file exists.)
class User < ApplicationRecord
mount :avatar, ...
This is painful. Consider using Microsoft Office or switching careers. If you need to write < 20 letters consider doing it manually.
So you didn't listen and here it comes:
.ods
spreadsheet (.xls
, .xlsx
, .ods
). Use any columns that work for you, but be consistent. I like to use one column for the address, one column for the salutation line.When making requests using curl, no cookies are sent or stored by default.
However, you can tell curl to re-use cookies received earlier (or forge your own cookies).
There are 2 command line switches you need to use:
-c
will write cookies to a given file-b
will read cookies from a given fileThe remote server sets a "foo" cookie to value "bar". We tell curl to store them to a file at /tmp/cookies
using the -c
switch.
$ curl -c /tmp/cookies http://httpbin.org/cookies/set?foo=bar
You may look at the file, ...
You should avoid using application models in your migrations. But how else could you create records in a migration?
The most basic way is to write plain SQL, but since INSERT statements are no pleasant write for Rubyists, here is a simple wrapper:
The helper method below takes a table name and a hash of attributes, which it inserts into the specified table. Copy it over to your migration and profit!
private
def insert_record(table, **attributes)
attributes.merge!...
When you print (or print preview) and elements are cut off (e.g. after 1st page, or "randomly") you should check your CSS rules for these:
Is there an element with "display: inline-block
" that surrounds your content? Make sure it has "display: block
" for printing.
This primarily affects Firefox and Internet Explorer. Chrome seems to be able to handle inline-block
elements in most cases.
Does the element itself, or a container, define "overflow: hidden
"? Use "overflow: auto
" (or maybe "overflow: visible
") instead.
Is th...
By default, browsers will not wrap text at syllable boundaries. Text is wrapped at word boundaries only.
This card explains some options to make browsers wrap inside a long word like "Donaudampfschifffahrt"
.
Modern browsers are able to hyphenate natively with the CSS property hyphens
:
hyphens: auto
There is also hyphens: none
(disable hyphenations even at ­
entities) and hyphens: manual
(hyphenation at ­
only).
This feature was integrated [just ...
chromedriver-helper
is not in the Gemfilechromedriver-helper
versionIf you install the chromedriver-helper
gem, but don't have it in you Gemfile, your selenium tests might fail with:
Selenium::WebDriver::Error::WebDriverError: unable to connect to chromedriver 127.0.0.1:9515
The reason is that chromedriver-helper
ov...
We're usually running Ubuntu LTS versions. Sometimes newer hardware requires packages from more recent Ubuntu releases that only come with 6 months of support. If there is really no other way, it's possible to install packages from later Ubuntu releases
Caution: Pay really close attention to what you're doing. Depending on the package, this process may require upgrading a lot of dependencies, possibly breaking the system! You really should not do this unless you've carefully calculated the impact on your system
First,...
Checking if a JavaScript value is of a given type can be very confusing:
typeof
and instanceof
which work very differently."foo"
) and sometimes an object (new String("foo")
) and each form requires different checksnull
(null
, undefined
and NaN
) and each has different rules for...An end-to-end test (E2E test) is a script that remote-controls a web browser with tools like Selenium WebDriver. This card shows basic techniques for fixing a flaky E2E test suite that sometimes passes and sometimes fails.
Although many examples in this card use Ruby, Cucumber and Selenium, the techniques are applicable to all languages and testing tools.
Your tests probably look like this:
When I click on A
And I click on B
And I click on C
Then I should see effects of C
A test like this works fine...
When your public-facing application has a longer downtime for server maintenance or long migrations, it's nice to setup a maintenance page to inform your users.
When delivering the maintenance page, be very careful to send the correct HTTP status code. Sending the wrong status code might get you kicked out of Google, or undo years of SEO work.
Here are some ways to shoot yourself in the foot during maintenance: