View

CarrierWave: How to generate versions with different file extensions

We use CarrierWave in many of our projects to store and serve files of various formats - mostly images. A common use case of CarrierWave's DSL is to "process" the original file in order to create multiple "versions", for example different resolutions of the same image.

Now we could go one step further: What if we want to create versions that have a different file extension than the original file? For example, let's assume we'd like to create a ve...

Repeats

Ruby: Referencing global variables with the built-in English library

With Ruby's build-in library English you can reference global variables with an english name. This makes you code easier to read and is also suggested by Rubocop's Style/GlobalVars cop.

Example before:

if 'foo' =~ /foo/
  puts $~[1] # => foo
end

Example after:

if 'foo' =~ /foo/
  puts $LAST_MATCH_INFO[1] # => foo
end

Require pitfall in Rails

The English library is not loaded by default in Rails. S...

Deprecated

How Rails and MySQL are handling time zones

When working with times and dates in Rails applications, you need to deal with the following problem:

  • In Rails, Time objects have a time zone. You can get the zone name by doing time_object.zone.
  • This zone is considered when doing time calculations, e.g. 10 AM CEST minus 8 AM UTC is zero.
  • A datetime in MySQL does not have a zone. It just stores the literal string "2010-05-01 12:00:00".
  • That means that Rails must make assumptions about timestamps loaded from and written to MySQL.

Rails has two completely different modes ...

Linked contentRepeats

PostgreSQL: WITH Queries (Common Table Expressions)

PostgreSQL's Common Table Expressions (CTEs) can be used to extract sub-queries from bulky SQL statements into a temporary table to be referenced instead.

This is most useful to avoid ugly joins or sub-selects. CTEs can be used for SELECT, INSERT, UPDATE or DELETE.

Example (from the PostgreSQL docs):

WITH regional_sales AS (
        SELECT region, SUM(amount) AS total_sales
        FROM orders
        GROUP BY region
     ), top_regions AS (
        SELECT region
        FROM regional_sales
        WHERE total_sales > (SELEC...
Linked contentRepeats

count vs. size on ActiveRecord associations

TLDR

  • When counting records in an association, you should use #size in most cases.
  • It will not work if the parent record has never been saved. Also there are finer distinctions between #size and #count. See below.

count

  • Always makes a COUNT(*) query if a counter cache is not set up.
  • If a counter cache is set up on the association, #count will return that cached value instead of executing a new query.

size, if the association has already been loaded

  • Counts elements in the already loaded array.
  • Does not ...
Repeats

BigDecimal arithmetic in Ruby

Ruby comes with a class BigDecimal which you can use for arbitrary precision arithmetic. You should use BigDecimal instead of Float whenever you care about rounding errors, e.g. whenever you are dealing with money.

You should remember these two rules when working with BigDecimal values:

  • When you add or multiply a BigDecimal with another BigDecimal, the ...
Linked contentRepeats

Lazy-loading images

Since images are magnitudes larger in file size than text (HTML, CSS, Javascript) is, loading the images of a large web page takes a significant amount of the total load time. When your internet connection is good, this is usually not an issue. However, users with limited bandwidth (i.e. on mobile) need to mine their data budget better.

One popular strategy to improve the website performance is to not load images until they enter the viewport – aka "lazy-loading images".

General Issues

  • Crawlers do not execute JavaScript (generally sp...
Repeats

How to evaluate CSS media queries in JavaScript

To make CSS rules dependent on the screen size, we use media queries:

@media (max-width: 500px) {
  // rules for screen widths of 500px or smaller
}

Browsers will automatically enable and disable the conditional rules as the screen width changes.

To detect responsive breakpoints from JavaScript, you may use the global matchMedia() function. It is supported in all brow...

Repeats

How to grep through the DOM using the Capybara API

When your Cucumber feature needs to browse the page HTML, and you are not sure how to express your query as a clever CSS or XPath expression, there is another way: You can use all and find to grep through the DOM and then perform your search in plain Ruby.

Here is an example for this technique:

Then /^I should see an image with the filename...
Repeats

Deterministic ordering of records by created_at timestamp

Creating records in specs can be so fast that two records created instantly after one another might have the same created_at timestamp (especially since those timestamps don't have an indefinitely high resolution). When ordering lists by timestamps, you should therefore always include a final order condition using the primary key of the table.

class Photo < ActiveRecord::Base
  scope :by_date, -> { order('created_at DESC, id DESC') }
end

Photo.by_date

Remember to include the id field in the database index.

Repeats

PSA: "index: true" in Rails migrations does not work as you'd expect

Several Rails migration methods accept index: true as an option to create an index. In some cases (like #add_column), this option is silently discarded. Know what you are doing, or use #add_index instead.

Example

Consider the following migration.

class CreateExamples < ActiveRecord::Migration
  def change
    create_table :examples do |t|
      t.references :category, index: true
      t.boolean :positive, index: true
      t.integer :number_of_participants, index: true
    end

    add_referen...
Linked contentRepeats

Ruby: A small summary of what return, break and next means for blocks

Summary

  • Use return to return from a method. return accepts a value that will be the return value of the method call.
  • Use break to quit from a block and from the method that yielded to the block. break accepts a value that supplies the result of the expression it is “breaking” out of.
  • Use next to skip the rest of the current iteration. next accepts an argument that will be the result of that block iteration.

The following method will serve as an example in the details below:

def example
  puts yield
  puts 'don...
Linked contentRepeats

Active Record: 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]
)

Rails: Concurrent requests in development and tests

With puma you can have concurrent requests. There are two concepts on how Puma can handle two incoming requests: Workers and Threads.

Workers

Puma can have multiple workers. Each worker is a process fork from puma and therefore a very heavy instance and can have multiple threads, that handle the incoming requests.

Example: A Puma server with 2 workers and 1 thread each can handle 2 request in parallel. A third request has to wait until the thread of one of the workers is free.

Threads

Rails is thread-safe since version 4 (n...

Repeats

Async control flow in JavaScript: Promises, Microtasks, async/await

Slides for Henning's talk on Sep 21st 2017.


Understanding sync vs. async control flow

Talking to synchronous (or "blocking") API

print('script start')
html = get('/foo')
print(html)
print('script end')

Script outputs 'script start', (long delay), '<html>...</html>', 'script end'.

Talking to asynchronous (or "evented") API

print('script start')
get('foo', done: function(html) {
  print(html)
})
print('script end')

Script outputs 'script start', `'...

Linked contentRepeats

How to use Parallel to speed up building the same html partial multiple times (for different data)

The parallel-gem is quite easy to use and can speed up rendering time if you want to render the same partial multiple times (e.g. for rendering long lists of things).
If your parallelized code talks to the database, you should ensure not to leak database connections.

Consider you want to render a list of groups with their members as json. You can use a partial for the rendering of group members, b...

How to: Throttle CPU in Google Chrome

Chrome allows you to throttle the Network and the CPU. Both settings are useful to measure the performance of you application and reproduce performance issues (Example Debugging frontend performance issues with Chrome DevTools).

You find the settings in: DevTools > Performance > Capture Settings (Gear icon in the right corner) > `CPU: No...

Video transcoding: Web and native playback overview (April 2020)

Intro

Embedding videos on a website is very easy, add a <video> tag to your source code and it just works. Most of the time.

The thing is: Both the operating system and Browser of your client must support the container and codecs of your video. To ensure playback on every device, you have to transcode your videos to one or more versions of which they are supported by every device out there.

In this card, I'll explore the available audio and video standards we have right now. The goal is to built a pipeline that...

This website uses short-lived cookies to improve usability.
Accept or learn more