3977 cards
Linked contentRepeats

How to reload a belongs_to association

To reload a single-item association in Rails 5+, call #reload_<association>:

post.reload_author

In older Railses you can say

post.author(true)
Repeats

Ruby: How to use prepend for cleaner monkey patches

Let's say you have a gem which has the following module:

module SuperClient

  def self.foo
    'Foo'
  end
  
  def bar
    'Bar'
  end

end

For reasons you need to override foo and bar.

Keep in mind: Your code quality is getting worse with with each prepend (other developers are not happy to find many library extensions). Try to avoid it if possible.

  1. Add a lib/ext/super_client.rb to your project (see How to organize monkey patches in Ruby on Rails projects)
  2. Add the extension, which overr...
Repeats

Capybara: Quick checking for element presence (without retries or timeout)

Element finding is a central feature of Capybara. Since #find is normally used to get elements from the current page and interact with them, it's a good thing that some Capybara drivers (e.g. Selenium) will wait an amount of time until the expected element shows up. But if Capybara cannot #find it at all, you'll get an error.

if page.find('.that-element')
  # Do something
else
  # Never happens because #find raises
end

In order to simply check whether an element is present, without errors raised, you can use #has_css?. It wil...

Repeats

Pitfall: ActiveRecord callbacks: Method call with multiple conditions

In the following example the method update_offices_people_count won't be called when office_id changes, because it gets overwritten by the second line:

after_save :update_offices_people_count, :if => :office_id_changed? # is overwritten …
after_save :update_offices_people_count, :if => :trashed_changed? # … by this line

Instead write:

after_save :update_offices_people_count, :if => :office_people_count_needs_update?

private

def office_people_count_needs_update?
  office_id_changed? || trashed_changed?
end

Or, move t...

ImageMagick: Converting SVG to PNG

Conversion

ImageMagick can convert SVGs to PNG.

convert input.svg output.png

If the SVG has a size of 24x24 (viewbox="0 0 24 24"), the resulting PNG will also have a size of 24x24.

Conversion with resizing (poor results)

If you want the PNG in a larger size, the naive approach would be to use the resize flag.

convert -resize 96x96 input.svg output.png

However, this results in a PNG with a rather poor resolution, as the resize conversion does not automatically scale the SVG.

Correlation of size and den...

The TCF 2.0 (Tranparency and Consent Framework) standard, and what you should know about it

The Interactive Advertising Bureau (IAB) Archive is a European marketing association which has introduced a standard how advertising can be served to users in line with the General Data Protection Regulation (GDPR). This standard is called the TCF 2.0 (Transparency and Consent Framework). If you want to integrate any kind of advertising into a website, chances are the advertising network will require your website to implement that standard. This is a very brief overview of what this means:

The basic idea in the TCF 2.0 ...

Ad blockers: How to debug blocked elements

Some users might use Adblock Plus or similar browser plugins to reduce the number of ads displayed. If you run into an issue that your application or part of an application is blocked, this card will give you some guidance on how to debug it.


In general ad blocking is not an issue for most of our web apps. But if your application uses iframes or is embedded in another site it's more prone to it.

Blocked elements most of the time appear to the user as empty frames in the page. The indicator icon of the ad blocker also gives ...

Linked content

vagrant < 2.2.9: handle conflicting host only adapter

I sometimes had the issue that I received an error when starting an existing vagrant box with vagrant up:

A host only network interface you're attempting to configure via DHCP
already has a conflicting host only adapter with DHCP enabled. The
DHCP on this adapter is incompatible with the DHCP settings. Two
host only network interfaces are not allowed to overlap, and each
host only network interface can have only one DHCP server. Please
reconfigure your host only network or remove the virtual machine
using the other host only network.
...
Repeats

Why two Ruby Time objects are not equal, although they appear to be

So you are comparing two Time objects in an RSpec example, and they are not equal, although they look equal:

expected: Tue May 01 21:59:59 UTC 2007,
     got: Tue May 01 21:59:59 UTC 2007 (using ==)

The reason for this is that Time actually tracks fractions of a second, although #to_s doesn't say so and even though you probably only care about seconds. This means that two consecutive calls of Time.now probably return two inequal values.

Consider freezing time in your tests so it is not dependent on the speed of the executi...

Linked contentRepeats

Rspec: Scope your custom matchers to example groups

When you find yourself in the situation that you would like to define a custom matcher in your specs, but you do not want to define a global matcher since you need it only for your specific test, there are two ways to do it:

Custom matcher for a single group

If you're only going to include a matcher once, you can also use the matcher macro within an example group Archive :

describe "group" do
  
  matcher :...
Linked content

Google Chrome now has a JavaScript bundle visualizer

Similar to the Webpack Bundle Analyzer, Chrome's new Lighthouse feature …

… shows a visualisation of your JavaScript bundles. It's compatible with sourcemaps and is great for understanding large JavaScript modules used by your page. It can also visualise unused bytes.

This is very helpful to visualize Javascript files in development. It also works on production code, where its usefulness depends on the structure of the productive Javascr...

Repeats

ES6 imports are hoisted to the top

From Exploring ES6 Archive :

Module imports are hoisted (internally moved to the beginning of the current scope). Therefore, it doesn’t matter where you mention them in a module and the following code works without any problems:

foo();
import { foo } from 'my_module';

Footgun example

When you're not aware of import hoisting you may be surprised that your code runs in a different order than you see in the source file.

The example below is taken from the [...

no passenger served applications running error when deploying via capistrano

When deploying with capistrano it's possible you get this "error" message:

*** [err :: example.com] There are no Phusion Passenger-served applications running whose paths begin with '/var/www/example.com'.
*** [err :: example.com] 

This is just because there were no running passenger process for this application on the server which could be restarted. It's not a real error. The application process will start if the first request for this app hits the appserver.

The output appears as err because it's printed to stderr.

Dep...

Repeats

Load order of the environment

Rails 3, 4, 5, 6

  1. config/application.rb
  2. config/environment.rb before the initialize! call (we don't usually edit this file)
  3. The current environment, e.g. environments/production.rb
  4. Gems
  5. Vendored plugins
  6. All initializers in config/initializers/*.rb
  7. config/environment.rb after the initialize! call (we don't usually edit this file)

Rails 2

  1. Code in config/preinitializer.rb (if it exists)
  2. environment.rb, code above the Rails::Initializer.run block (put constants here if yo...
Linked content

Finding ancestors with Capybara

Modern versions of Capybara include a finder method #ancestor which allows you to find a parental element using CSS or XPath.

If you previously did something like this:

field.find(:xpath, './ancestor::div[contains(@class, "form-group")]')

..and prefer CSS, you may rewrite it:

field.ancestor('div.form-group')

Both versions will return the outermost matching element. Use the #order option find the closest parent:

field.ancestor('div.form-group', order: :reverse)

Hints for debugging MySQL InnoDB deadlocks

Deadlocks only occur if two transactions in separate threads compete for the same rows in the database. They usually (but not necessarily) only happen when trying to update or otherwise lock several rows in different order.

Solving deadlocks is potentially complicated, so here are a few pointers:

  • MySQL should always detect the deadlock right when it happens, and will throw an error to one of the offending threads. This error states the SQL statement that this thread was currently waiting for, and that tried to acquire one of the competin...
Linked contentRepeats

Advisory: Excel converts CSV entries to formulas

If your application exports CSV, be advised that Excel and other spreadsheet applications treat certain cells (those starting with =, +, - or @) as formulas.

This is an issue if you output user input. Not only is it probably not what you want, it also poses a security risk. See the link for attack vectors.

Note that current Excel versions will warn the user when opening the file. At least for the code execution vulnerability, these three warnings seems adequate to me.

Code execution warnings:

![Image](/makandra/47624/attach...

Repeats

Ruby: Making your regular expressions more readable with /x and alternative delimiters

The following two hints are taken from Github's Ruby style guide Archive :

If your regular expression mentions a lot of forward slashes, you can use the alternative delimiters %r(...), %r[...] or %r{...} instead of /.../.

 %r(/blog/2011/(.*))
 %r{/blog/2011/(.*)}
 %r[/blog/2011/(.*)]

If your regular expression is growing complex, you can use the /x modifier to ignore whitespace and comments or use named groups or...

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