Webpack: Automatically generating an icon font from .svg files
Over the years we have tried several solution to have vector icons in our applications. There are many ways to achieve this, from SVGs inlined into the HTML, SVGs inlined in CSS, JavaScript-based solutions, to icon fonts.
Out of all these options, the tried and true icon font seems to have the most advantages, since
- icon fonts are supported everywhere
- they perform well and require no JavaScript at all
- their icons align nicely with text
- their icons automatically inherit color and size of the surrounding text
The big issue used to b...
VCR and the webdrivers gem
If you're using the webdrivers gem and VCR together, depending on your configuration, VCR will yell at you regulary.
The webdrivers gem tries to update your webdrivers on your local machine. To do so, it checks the internet for newer versions, firing an HTTP-request to e.g. https://chromedriver.storage.googleapis.com
You can "fix" this in multiple ways:
-
Update your drivers on your machine with
RAILS_ENV=test rake webdrivers:chromedriver:update
-
Ignore the driver update-URL in your ...
Katapult EOL
Katapult was an endeavor to dramatically speed up starting a new Rails application. However, it turned out to save less time than expected, while requiring more time for maintenance than anticipated. Since its benefits fell too low, we have decided to not continue developing Katapult.
You can still use Katapult for generating ready-to-run applications with model CRUD, authentication and all of Katapult's features, but the rapid development of the web will quickly render the generated code antiquated. Nevertheless, its architecture may remai...
How to use helper methods in a controller
Rails 3+
view_context.helper_method('args')
Rails 2
ApplicationController.helpers.helper_method('args')
Also see How to use helper methods inside a model.
There is no real performance difference between "def" and "define_method"
You can define methods using def
or define_method
. In the real world, there is no performance difference.
define_method
is most often used in metaprogramming, like so:
define_method :"#{attribute_name}_for_realsies?" do
do_things
end
Methods defined via define_method
are usually believed to have worse performance than those defined via def
.
Hence, developers sometimes prefer using class_eval
to define methods using def
, like this:
class_eval "def #{attribute_name}_for_realsies?; do_things; end"
You can be...
Concerned about Concerns?
With Rails 4, Concerns have become the “official” solution to the big-models problem. However, there’s a fair amount of controversy about this topic in the community. Not everyone is convinced that Concerns are the “right“ solution to the problem of AR models becoming too big.
In this talk we will see what Rails Concerns are and how can we use them to keep our models fit. More interestingly, we’ll discuss the trade-offs of this technique, the different views in the community and a couple of alternatives.
Using Bumbler to Reduce Runtime Dependencies - The Lean Software Boutique
Tool to show you which gems are slow to load:
➜ git:(master) ✗ bundle exec bumbler
[################################################# ]
(49/65) travis-lint...
Slow requires:
110.21 render_anywhere
147.33 nokogiri
173.83 haml
179.62 sass-rails
205.04 delayed_job_active_record
286.76 rails
289.36 mail
291.98 capistrano
326.05 delayed_job
414.27 pry
852.13 salesforce_bulk_api
rspec_candy 0.4.0 released
- Now supports RSpec 3 and Rails 4
- Drops support for
state_machine
, which has some issues with Rails 4 and isn't actively maintained
Cronjobs: "Craken" is dead, long live "Whenever"
Our old solution for cronjobs, the "craken" plugin, is no longer maintained and does not work on Rails 3.2+.
We will instead use the whenever gem.
"Whenever" works just like "craken", by putting your rake tasks into the server's cron table. Everything seems to work just like we need it.
Installation for new projects
-
Add "whenever" to your
Gemfile
:group :deploy do gem 'whenever', require: false end
-
Add it to your
config/deploy.rb
:
...
How to: Use Ace editor in a Webpack project
The Ace editor is a great enhancement when you want users to supply some kind of code (HTML, JavaScript, Ruby, etc).
It offers syntax highlighting and some neat features like auto-indenting.
For Webpack 3+
Integrate as described in the documentation. For example load ace Editor like this:
function loadAceEditor() {
return import(/* webpackChunkName: "ace" */ 'ace-builds/src-noconflict/ace').then(() => {
return import(/* webpackChunkName: "ace" */ 'ace-builds/webpack-r...
Debugging flickering VCR tests
We often use VCR to stub external APIs. Unfortunately VCR can have problems matching requests to recorded cassettes, and these issues are often hard to debug.
VCR's error messages mostly look like this and are not very helpful:
An HTTP request has been made that VCR does not know how to handle:
POST http://another-site.de:9605/json/index
VCR fails if the request does not exactly look like the request it has recorded. If the request is d...
Performance analysis of MySQL's FULLTEXT indexes and LIKE queries for full text search
When searching for text in a MySQL table, you have two choices:
- The LIKE operator
- FULLTEXT indexes (which currently only work on MyISAM tables, but will one day work on InnoDB tables. The workaround right now is to extract your search text to a separate MyISAM table, so your main table can remain InnoDB.)
I always wondered how those two methods would scale as the number of records incr...
Unpoly: Testing values for presence or blankness
In Ruby on Rails, all objects have a useful blank?
method. It returns true for nil
but also for empty strings or empty arrays. There is also a universal method present?
which returns true
for all values that are not blank?
.
In JavaScript you need to roll your own implementation of blank?
and present?
.
If your application uses [Unpoly](...
How to make Rational#to_s return strings without denominator 1 again
The way Rational#to_s
works on Ruby has changed from Ruby 1.9 on. Here is how to get the old behavior back.
You may want this for things where Rationals are being used, like when subtracting Date
objects from one another.
What's happening?
Converting a Rational
to a String
usually does something like this:
1.8.7 > Rational(2, 3).to_s
=> "2/3"
1.9.3 > Rational(2, 3).to_s
=> "2/3"
2.0.0 > Rational(2, 3).to_s
=> "2/3"
However, when you have a Rational
that simplifies to an integer, you will only get a St...
Capturing signatures on a touch device
If you need to capture signatures on an IPad or similar device, you can use Thomas J Bradley's excellent Signature Pad plugin for jQuery.
To implement, just follow the steps on the Github page.
The form
If you have a model Signature
with name: string, signature: text
, you can use it with regular rails form like this:
- form_for @signature, :html => { :class => 'signature_form' } do |form|
%dl
%dt
= form...
Careful with '||=' - it's not 'memoize'
When you do something like this in your code:
def var_value
@var ||= some_expensive_calculation
end
Be aware that it will run some_expensive_calculation every time you call var_value if some_expensive_calculation returns nil.
This illustrates the problem:
def some_expensive_calculation
puts "i am off shopping bits!"
@some_expensive_calculations_result
end
When you set @some_expensive_calculations_result to nil, ||= runs some_expensive_calculation every time....
Find geocoded records that are close to a location (radius search)
When you have objects in your database that hold latitude and longitude and you want to find others that are close to given coordinates you can use the Graticule gem.
Graticule
Graticule offers several methods to compute the distance between two geo-dated objects but fetching records from the database that are within a given radius of a location is a bit trickier:
def close_destinations(latitude, longitude)
distance_sql = Graticule::Distance::Spherical.to_sql(:latitude => l...
UI Sortable on table rows with dynamic height
UI sortable helps reordering items with drag 'n drop. It works quite fine.
Proven configuration for sorting table rows
When invoking the plugin, you may pass several options. This set is working fine with table rows:
$tbody.sortable # Invoke on TBODY when ordering tables
axis: 'y' # Restrict drag direction to "vertically"
cancel: 'tr:first-child:last-child, input' # Disable sorting a single tr to prevent jumpy table headers
containment: 'parent' # Only drag within this container
placehol...
Manually uploading files via AJAX
To upload a file via AJAX (e.g. from an <input type='file'>
) you need to wrap your params in a FormData
object.
You can initialize a FormData
using the contents of a form:
var form = document.querySelector('form.my-form') // Find the <form> element
var formData = new FormData(form); // Wrap form contents
Or you can construct it manually, param by param:
var fileInput = document.querySelector('form input[type=file]');
var attachment = fileInput.files[0];
var f...
Putting static content on Cloudfront
We recently decided to put static content for HouseTrip.com to Amazon Cloudfront for a faster user experience. This happens fully automatically on deploy and is transparent in development. Together with a heavy use of sprites this sped up page load time quite nicely.
These are a couple of the problems you need to solve in order to do this:
- There is no good way to invalidate Cloudfront cached assets, and Cloudfront will ignor...
Auto-coerced virtual attributes with Virtus
We've since created ActiveType which has a restricted subset of Virtus' features. It might be enough for your needs.
We sometimes give our ActiveRecord models virtual attributes for values that don't need to be stored permanently.
When such a virtual attribute should contain integer values you might get unexpected behavior with forms, because every param is a string and you don't get the magic type casting that Rails would give you if it ...
MySQL 5.7.5 enables `ONLY_FULL_GROUP_BY` mode per default
When using GROUP BY
, MySQL now complains if the SELECT
includes columns which are not part of the GROUP BY
.
Reason:
There could be multiple values for those columns per group but only one value can be picked for the results.
The default behaviour of MySQL prior to version 5.7 will not complain and arbitrarily choose a value. But this leads to non-deterministic results. So MySQL now has enabled the only_full_group_by
setting by default to prevent this.
In Rails this could lead to some trouble, because scopes do not have sp...
How to make programming hard for yourself
For all of my professed admiration of Ruby on rails, I personally don't think that easier and more productive CRUD application writing will shake things up. I personally care very much about writing applications in a tenth of the time, but using Rails is like listening to Jaco Pastorius. The real learning experience comes when you try to duplicate the feat.
Deal with certain travis CI failures
Travis changed their default distribution from Ubuntu 14.04 (trusty) to 16.04 (precise). This might break your test setup for new builds.
You can solve this issue by freezing your test distribution in the .travis.yml
to Ubuntu 14.04 until you have the time to solve all the issues you will have in 16.04:
dist: trusty
Error details
Here are few indicators that you ran into this issue:
Connection to the PostgreSQL database does not work anymore
Your travis-ci builds might have started failing on the usual
psql -c...