The Ruby Object Model

In Ruby (almost) everything is an Object. While this enables a lot of powerful features, this concept might be confusing for developers who have been programming in more static languages, such as Java or C#. This card should help understanding the basic concepts of Ruby's object model and how things behave.


Usage of objects in Ruby

When working with objects in Ruby, you might think of a "container" that holds metadata, variables and methods. Metadata describes stuff like the object's class or its object_id whi...

RSpec: How to test the content of a flash message in a request spec

The ActionDispatch module of Rails gives you the helper method flash to access the flash messages in a response.

describe PostsController, type: :request do

  describe 'update' do

    it 'shows a success message on update' do
      post_record = create(:post)

      put "/posts/#{post_record.id}"

      # Same as @request.flash[:alert]
      expect(flash[:alert]).to eq('Post updated successfully.')
    end

  end


end

makandra/capybara-lockstep

capybara-lockstep can help you with flaky end-to-end tests:

This Ruby gem synchronizes Capybara commands with client-side JavaScript and AJAX requests. This greatly improves the stability of a full-stack integration test suite, even if that suite has timing issues.

Too many parallel test processes may amplify flaky tests

By default parallel_tests will spawn as many test processes as you have CPUs. If you have issues with flaky tests, reducing the number of parallel processes may help.

Important

Flaky test suites can and should be fixed. This card is only relevant if you need to run a flaky test suite that you cannot fix for some reason. If you have no issues...

CarrierWave: Default Configuration and Suggested Changes

CarrierWave comes with a set of default configuration options which make sense in most cases. However, you should review these defaults and adjust for your project wherever necessary.

You will also find suggestions on what to change below.

Understanding the default configuration

Here is the current default config for version 2:

config.permissions = 0644
config.directory_permissions = 0755
config.storage_engines = {
  :f...

Insomnia helps you querying your API

Insomnia is a GUI tool to help you communicating with an API. There are also other tools to do this, e.g. Postman or the command line tool cURL.

While it is quite similar to Postman, I found the UI to be less cluttered and therefore easier to use.

Image

The usage is almost self explanatory.

You can install it v...

Some tips for upgrading Bootstrap from 3 to 4

Recently I made an upgrade from Bootstrap 3 to Bootstrap 4 in a bigger project. Here are some tips how to plan and perform such an upgrade. The effort will scale with the size of the project and its structure. If your stylesheets already follow strict rules, it may take less time to adapt them to the new version.

Preparation

There are several gems and libraries that works well with bootstrap or provide at least stylesheets/plugins to easily integrate the bootstrap theme. But very often they only work with specific version or are no long...

ActiveType #change_association: Define { autosave: true } on parent models

Consider the following models and form models:

class Parent < ApplicationRecord
  has_many :children, class_name: 'Child', foreign_key: 'parent_id'
end

class Parent::AsForm < ActiveType::Record[Parent]
  change_association :children, class_name: 'Child::AsForm', foreign_key: 'parent_id', autosave: true, inverse_of: :parent

  accepts_nested_attributes_for :children
  validates_associated :children
end
class Child < ApplicationRecord
  belongs_to :parent, inverse_of: :children
end

class Child::AsForm < ActiveType::Reco...

WYSIWYG with Action Text

Rails 6 includes a WYSIWYG editor, Action Text. It works out of the box quite well, but chances are that you want to add some custom functionality. This card contains some tips how to achieve this.

Setup

Basically, follow the guide in the Rails documentation. The automated script may not work with the way webpacker is configured in your project, but it should be easy to fix.

If you don't want the default c...

Rails: How to use custom flash types in controllers

Rails supports alert and notice as default flash types. This allows you to use these keys as options in e.g. redirect_to and as a helper in views e.g. <%= notice %> (instead of flash[:notice]).

class SomeController < ApplicationRecord
  def create
    @user = User.create!
    
    redirect_to user_path(@user), notice: "#{@user} created!" 
  end
end

In case you are using Bootstrap as CSS framework you might also want to support flashes like success. This can be done with the add_flash_types method.

class Applicat...

Git: Parsing large diffs as a human

I just finished migrating a project from the Asset Pipeline to Webpacker, this is what my diff to master looks like:

5.825 files changed, 44.805 insertions(+), 529.948 deletions(-)
warning: inexact rename detection was skipped due to too many files.
warning: you may want to set your diff.renameLimit variable to at least 5134 and retry the command.

There is no way me or my peer reviewer is able to parse 500k+ lines of code. Fortunately, git has ...

Using the Truemail gem to validate e-mail addresses

The Truemail gem (not to be confused with truemail.io) allows validating email addresses, e.g. when users enter them into a sign-up form. It runs inside your application and does not depend on an external SaaS service.

Truemail supports different validation "layers":

  1. Regex validation: if the given address is syntactically valid
  2. DNS validation (called MX validation): if the given domain exists and can receive email
  3. SMTP validation: connects to the host received from DNS and starts a test d...

How to build a fully custom TinyMCE 5 dialog

TinyMCE is a WYSIWYG editor which is quite customizable.


  1. Add a custom button to the tinyMCE toolbar and tell tinyMCE to open a dialog with the route to your dialog's view.
tinymce.init({
  // ...
  toolbar: 'myCustomButton',
  setup: function(editor) {
      editor.ui.registry.addButton('myCustom Button', {
        ...

Using the alt attribute and the figcaption element in HTML

While both the alt attribute and the figcaption element provide a way to describe images, the way we write for them is different:

  • alt descriptions should be functional
  • figcaption descriptions should be editorial or illustrative

Rails developers: Have better context in Git diffs

Git diffs show the surrounding contexts for diff hunks. It does so by applying regular expressions to find the beginning of a context. When it comes to Ruby, however, it will not find method heads and travel up to the class definition:

@@ -24,7 +24,7 @@ class TicketPdf # <=== Actually expected here: the method definition
     ApplicationController.render(
       "tickets/index.html.haml",
       layout: "tickets",
-      assigns: { tickets: tickets }
+      assigns: { tickets: tickets, event_name: event_name }
     )
   end
 end
```...

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 downgrade Google Chrome in Ubuntu

If you're experiencing problems with your Google Chrome installation after an update, it might help downgrading Chrome to check if the problem disappears. Keep in mind though that running outdated software, especially web browsers, is in most cases not a good idea. Please verify periodically if you still need to run the old version or if an even more recently updated version fixes the problems introduced in your version.

Here's how to get old versions of Chrome for your Ubuntu installation:

First, go to [UbuntuUpdates](https://www.ubuntuup...

What's so hard about PDF text extraction? ​

There is a common view that extracting text from a PDF document should not be too difficult. After all, the text is right there in front of our eyes and humans consume PDF content all the time with great success. Why would it be difficult to automatically extract the text data?

Turns out, much how working with human names is difficult due to numerous edge cases and incorrect assumptions, working with PDFs is difficult due to the extreme flexibility given by the PDF format.

Simple form examples with bootstrap

Good reference how to build bootstrap forms with simple_form.

RubyMine: Restore main menu in Ubuntu

After a recent Ubuntu update I didn't see the main menu bar of the RubyMine IDE (File | Edit | View | ...) anymore.

This could be solved by changing a RubyMine registry entry:

  • Search "registry" within the "Actions" search
    • press ctrl + alt + n > click on Actions > type registry > click on Registry...
  • Scroll down to linux.native.menu and disable the checkbox

After rebooting RubyMine, you'll have gotten the menu bar back.

How to cycle through grep results with vim

grep is the go-to CLI tool to accomplish tasks like filtering large files for arbitrary keywords. When additional context is needed for search results, you might find yourself adding flags like -B5 -A10 to your query. Now, every search result covers 16 lines of your bash.

There is another way: You can easily pipe your search results to the VIM editor and cycle through them.

Example: Searching for local occurrences of "User"

vim -q <(grep -Hn -r "User" .)

# vim -q starts vim in the "quickfix" mode. See ":help quickfix"
# grep...

Vortrag: Content Security Policy: Eine Einführung

Grundidee

CSP hat zum Ziel einen Browser-seitigen Mechanismus zu schaffen um einige Angriffe auf Webseiten zu verhindern, hauptsächlich XSS-Angriffe.

Einschub: Was ist XSS?

XSS = Cross Site Scripting. Passiert wenn ein User ungefiltertes HTML in die Webseite einfügen kann.

<div class="comment">
  Danke für den interessanten Beitrag! <script>alert('you have been hacked')</script>
</div>

Rails löst das Problem weitgehend, aber

  • Programmierfehler weiter möglich
  • manchmal Sicherheitslücken in Gems oder Rails

Lösungsid...

Automatically validating dependency licenses with License Finder

"Open-source software (OSS) is great. Anyone can use virtually any open-source code in their projects."

Well, it depends. Licenses can make things difficult, especially when you are developing closed-source software. Since some OSS licenses even require the employing application to be open-sourced as well (looking at you, GPL), you cannot use such software in a closed-source project.

To be sure on this, we have developed a project-level integration of Pivotal's excellent [license_finder](https:/...

How to prevent Nokogiri from fixing invalid HTML

Nokogiri is great. It will even fix invalid HTML for you, like a browser would (e.g. move block elements out of parents which are specified to not allow them).

>> Nokogiri::HTML.fragment("<h1><p>foo</p><span>bar</span></h1>").to_s
=> "<h1></h1><p>foo</p><span>bar</span>"

While this is mostly useful, browsers are actually fine with a bit of badly formatted HTML. And you don't want to be the one to blame when the SEO folks complain about an empty <h1>.

To avoid said behavior, use Nokogiri::XML instead of Nokogiri::HTML whe...