The on_the_spot gem allows inline editing of data. In general this is something I prefer over forms: I do not want to switch to a new page to edit something, I want to edit it where I see it (I understand there are some very good cases for the standard show/edit pages).

So a very long while ago I created a small gem to edit data inline. It relies on the jEditable javascript, which is still working.

But how do you style the dynamically injected form?

In my projects, I use the translation files as follows, e.g. in on_the_spot.en.yml I write :

    ok: <button class="btn btn-primary btn-sm">Ok</button>
    cancel: <button class="btn btn-default btn-sm">Cancel</button>
    tooltip: Click to edit
    access_not_allowed: Access not allowed 

This will make sure the buttons are styled correctly. But if you try this, the input is too narrow, and everything is just squished together.

So add this little sprinkle of css to make everything look a little better:

.on_the_spot_editing {
  input, select {
    width: auto !important;
    height: 30px !important;

    margin-right: 5px !important;

    //display: block;

    padding: 6px 12px;
    font-size: 14px;
    line-height: 1.42857143;
    color: #555555;
    background-color: #fff;
    background-image: none;
    border: 1px solid #ccc;
    border-radius: 4px;

    -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
    box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
    -webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
    -o-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
    transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
  textarea {
    width: 80%;

  .btn {
    margin: 1px !important;

What inline editing solution are you using with rails?

I am currently contemplating to switch over to start using vue.js for javascript sprinkles like this.

If you started using FontAwesome-5 in a Turbolinks project, you will quickly notice the icons disappear after the first page reload. So how can we fix that? I did not immediately find a reference inside the FontAwesome documentation, but luckily google proved helpful and I found this issue

Inside the issue I found the fix which I applied and worked for me. I created a new file app/javascripts/fix_fontawesome_reload.js with the following content

document.addEventListener("turbolinks:before-render", function(event) {

which was then automatically included in application.js (because I have the require_tree line).

I just read this article titled Useful RSpec trick for testing method with arguments which shows a nifty way to write a repetitive test-suite where you want to verify different arguments give the correct/expected result.

The method proposed by the author looks like this:

RSpec.describe Daru::Index do
  let(:index) { [:a, :b, :c, :d] }

  describe '#pos' do
    subject { index.method(:pos) }

    context 'by label' do
      its([:a]) { eq 0 }
      its([:a, :c]) { eq [0, 2] }
      its([:b..:d]) { eq [1, 2, 3] }
      # .. and so on

Which is looking very readable and compact! This solution makes a lot of use of subject, let and relies on its to make it work.
Then the author proceeds to list a few more basic/default rspec ways but does not list how I in general write tests like that.

Not sure if it is more readable or not, but imho it is in general a lot less work, it is usable for a all kinds of repetitive tests.

Let’s see how it looks:

RSpec.describe Daru::Index do
  let(:index) { [:a, :b, :c, :d] }

  describe '#pos' do
    context 'by label' do 
      [ [[:a], 0],
        [[:a, :c], [0,2] ],
        [[:b ..:d], [1,2,3] ], 
        # and so on
      ].each do |arr|
        it "returns #{arr[1].inspect} for #{arr[0].inspect}" do 
          expect(index.pos(arr[0]).to eq(arr[1])

(note: not actually sure if this code works, but you get the gist of it I hope)

So I use ruby meta-programming to define a whole test-suite when the file is loaded, and when I need
to test another input-output, I can just add it to the list, no need to copy-paste.

In our GIS web-application we use leaflet with the superb sidebar-v2 component to have some fold-out pages and command-icons in one place. But we suddenly encountered a bug when users/developers started upgrading to chrome 62. Very weird rendering bug. The icons suddenly were no longer centered inside the lu > li items but only the top half was visible. As if the icons were shifted down.

To get a little more technical: the sidebar is a bar filled with icons and these are actually an unordered list, and to center the icons inside the foreseen space we have something like, in short:

ul > li { height: 40px; }
ul > li > a { 
  height: 100%; 
  line-height: 40px;

which is all in itself a pretty standard way to align “text” (icons in our case) vertically. So why is it broken now? Chrome 62 seems to add some kind of padding/margin, except setting those explicitly has not effect.

If I removed the line-height the icons came into view correctly, but they were not centered in the foreseen space anymore.

Luckily, I was not the first to encounter this issue and this bug
was also already reported to google as well and a fix is underway
Unfortunately (?) the bug was not severe enough to actually halt going live of version 62 and or but it will be fixed in 63.

Luckily fixing the layout is quite simple, just add

 ul > li { 
   list-style-type: none;

and then it renders correctly over all platforms again.

So to recap: if your unordered lists have hidden overflows and are suddenly broken in chrome 62 this might help you as well.

I have an audit-log table with +300M rows and while most messages are just confirming we performed some very repetitive action, I was thinking of an easy way to compress the data: when a month is over, instead of adding 1000 lines per day with the message “CHECKED IT”, replace them with 1 line saying we “CHECKED IT [logged X times on day Y]”. Wrote the code, and that was pretty easy. But then came the moment I had to run this, and the simplest query to check the number of messages:

select count(*) as count
from audit_logs
where created_at < '2016-01-01' 
  and created_at > '2015-12-01'       
  and message = 'Checking for new map-requests'  
  and organization_id = 3

took 15 seconds. So then I checked my indexes: I had only an index on organization_id.

I read an article on the best way to create an index when searching for ranges, and it suggested a combined index on the equality operator first, and then the range second, so in my case I added a migration with the following addition

add_index :audit_logs, [:organization_id, :created_at]  

Rerunning the query showed an immense improvement, and now the query only took a mere 20ms :) :) :)

Before, with iPhotos it was pretty easy to extract files: just drag and drop and they would have the exact same date and time as when they were imported/taken. Now, with the Photos app, this is no longer the case. WTF. A dropped file gets the current date and time. While I can understand why this is the case, it is not very convenient.

Luckily there is another way to copy files out of your Photos library.

If you visit the Pictures folder, you can see a (in my case very large) file called Photos Library.photoslibrary. If you right click and select Show Package Contents you can browse the individual files within the library. The images can be found in the Masters folder. The files/folders are organized by year/month/day which might not make sense to you, but I find it very useful.

I copied the entire Masters folder to my external drive, and then every image-file retained its original timestamp (yes!).

Now I can free some diskspace without any hesitation :)

… and then I encountered a bug in Postgis 2.0.4. Fuck. ST_geomfromgeojson rounds my z-values to integers, effectively making them useless.

I have a little example demonstrating this, and so I imagined to submit a bug. Unfortunately the bug-tracker requires an OS-Geo account, and to get that I need to write an email to get a “mantra” (see form ). Done that.

So what did I do (note just random-numbers):

insert into original_be_geometries(originally_type, originally_id, geom) 
values ('Test', 1, ST_setSRID(ST_GeomFromGeoJSON('{"type":"LineString","coordinates":[[1.23445,2.234455,3.33445],[4.12345,5.12345,6.56789],[7.012,8.111,9.0001]]}'), 31370) ); 

some random-numer, but if I then do something like select st_astext(geom) from original_be_geometries where originally_type= 'Test'; I get

LINESTRING Z (1.23445 2.234455 3,4.12345 5.12345 6,7.012 8.111 9)

Instead if I use ST_GeomFromText it does work:

insert into original_be_geometries(originally_type, originally_id, geom) 
values ('Test', 2, ST_setSRID(ST_GeomFromText('LINESTRING Z (1.23445 2.234455 3.33445, 4.12345 5.12345 6.56789, 7.012 8.111 9.0001)'), 31370) ); 

returns the expected geometry

LINESTRING Z (1.23445 2.234455 3.33445,4.12345 5.12345 6.56789,7.012 8.111 9.0001)

So I am going to switch my workflow from exporting geojson to exporting WKT’s which I can then use to import. Now if only oracle supported 3d geometries when exporting to WKT this would be easy :eye-roll: :le-sigh: :rolls-up-sleeves: :)

[UPDATE] My team-mate has Postgis 2.2.2 and there this just works. I did not find this bugfix in the changelog, but this is good news. Damn. Now I have to upgrade my postgresql/postgis. Using brew. OMG! Last time I lost a weekend trying to get it fixed, I think I will still write my own sdo2wkt3d instead ;) (and update later).

Let me quickly introduce WiceGrid, if you do not know yet: it is a super-gem that will allow you to easily show a list/grid of items, and allow easy filtering/searching/pagination.

For rails there is, afaik, no better alternative. There are some javascript/jquery driven dynamic grids, but for me the big advantage is that with WiceGrid all work is done server-side, which is ideal when handling large sets of data.

Since you can just render html in any column, we do for instance the following for our KLIP platform :

Screen Shot 2016-06-05 at 21.08.43

In our first we show our internal identifier, and the external identifier. In code this looks like this:

g.column name: 'Id', in_csv: false do |pr|
  render 'title_with_info', plan_request: pr

and the partial title_with_info looks like

  = plan_request.ident
  = plan_request.maprequest_id

But now the problem is: how can we, when filtering, automatically look for both fields? WiceGrid automatically handles one field, but not both. Luckily, WiceGrid allows us to define custom filter types. What we want is:

  • we want the filter to just look like a standard string field
  • we want to build a query which will search for ident or maprequest_id.

Adding your own custom filter types is not entirely clear in the documentation, I had to take a look at the code to fully understand it. So that’s why I decided to write it in detail here.

It takes three steps:

  • define a class to create the correct filter (a conditions generator)
  • define a custom filter_type inside WiceGrid, using your custom class
  • use the class in the column definition

Create Conditions Generator

Inside lib/wice/columns add a new file called conditions_generator_column_plan_request_identifier.rb and add the following content:

module Wice
  module Columns
    class ConditionsGeneratorColumnPlanRequestIdentifier < ConditionsGeneratorColumn  #:nodoc:

      def generate_conditions(table_alias, opts)   #:nodoc:
        if opts.kind_of? String
          string_fragment = opts
          negation = ''
        elsif (opts.kind_of? Hash) && opts.has_key?(:v)
          string_fragment = opts[:v]
          negation = opts[:n] == '1' ? 'NOT' : ''
          Wice.log "invalid parameters for the grid string filter - must be a string: #{opts.inspect} or a Hash with keys :v and :n"
          return false
        if string_fragment.empty?
          return false

        table_name = @column_wrapper.alias_or_table_name(table_alias)
        op = ::Wice.get_string_matching_operators(@column_wrapper.model)
        search_value = "%#{string_fragment}%"

            " #{negation}  (#{table_name}.ident #{op} ? OR #{table_name}.external_id #{op} ?)",
            search_value, search_value

This class is actually almost copied from the standard column generator, except I generate a different condition at the end, where I compare with two fields with an OR operator. This way I will find results if either the ident or the external_id matches the search-value.

Define filter type in config

In config/wice_grid_config.rb add the following:

  plan_request_identifier_filter:  ['ViewColumnString', 'Wice::Columns::ConditionsGeneratorColumnPlanRequestIdentifier']

We just use the standard ViewColumnString to just show us a string filter.

Use the filter_type in the column

To enable the filter in the column, we just have to write the following:

g.column name: 'Id', attribute: 'ident', filter_type: :plan_request_identifier_filter, in_csv: false do |pr|
  render 'title_with_info', plan_request: pr

When you encounter SSL errors when installing gems on Windows, the easiest workaround is to change your sources from https://... to http://.... But … I am an avid user/fan of and today I suddenly started getting the error on their domain.

So at first I feared that rails-assets had stopped as foreseen (in this ticket), but the site was still reachable, and actually they switched (imho just two days ago) to a new maintainer, which is awesome: the future of rails-assets is safe for now.

But there is no rose without a thorn and now rails-assets enforces TLS (which is actually a good thing), so it is always SSL and gem cannot ignore SSL anymore. Doh! So I was stuck on windows.

I tried to make gem command ignore ssl errors regardless, by creating c:\ProgramData\gemrc with the following content:

:ssl_verify_mode: 0 

and that partly worked: I was now able to fetch the index, but now I received the SSL error on the first gem retrieved from rails-assets, so I was still not in the clear. I had to make sure the SSL verification actually worked!

Fortunately, after some googling this proved easier then expected! The root cause is that ruby on windows (or openssl) has no default root certificate. So I found a good description how to fix that on windows.

I used the boring/easy/manual approach, in short:

  • download the cacert.pem file from I saved this to my ruby folder (e.g. c:\ruby21).
  • add an environment variable SSL_CERT_FILE, so ruby can pick it up. E.g. in your command prompt type set SSL_CERT_FILE=C:\ruby21\cacert.pem. To make this a permanent setting, add this to your environment variables.

In a system I am helping to develop a person can be linked to a myriad of things, including themselves, so we use a relation table PersonRelation defined as follows

 class PersonRelation
   belongs_to :person
   belongs_to :personifiable, :polymorphic => true
   belongs_to :person_relation_type

So a person could be linked to different “personifiable” things, and sometimes the meaning of the relation can change (e.g. a person could be an owner or a renter –expressed by the relation type).

In our datamodel, a person is actually a “legal person”, so it could also be an organisation, and an organisation can have contacts. Logically a contact belongs to one or more organisation by following the association in the reverse direction.

When using rails 3+ up until 4.0 we wrote the association as follows:

  has_and_belongs_to_many :contacts,
                          :join_table => "person_relations",
                          :class_name => "Person",
                          :foreign_key => "person_id",
                          :association_foreign_key => "personifiable_id",
                          :readonly => false,
                          :conditions => ["personifiable_type = ? and people.archived_at is null and person_relations.archived_at is null and person_relation_type_id=?", "Person", PersonRelationType::CONTACT],
                          :insert_sql => proc {|record| "INSERT INTO person_relations(person_id, personifiable_id, personifiable_type, person_relation_type_id, created_at, updated_at) VALUES('#{}', '#{}', 'Person', 6, current_timestamp, current_timestamp)" }

  has_and_belongs_to_many :organisations,
                          :join_table => "person_relations",
                          :class_name => "Person",
                          :association_foreign_key => "person_id",
                          :foreign_key => "personifiable_id",
                          :readonly => false,
                          :conditions => ["personifiable_type = ? and people.archived_at is null and person_relations.archived_at is null and person_relation_type_id=?", "Person", PersonRelationType::CONTACT],
                          :insert_sql => proc {|record| "INSERT INTO person_relations(person_id, personifiable_id, personifiable_type, person_relation_type_id, created_at, updated_at) VALUES('#{}', '#{}', 'Person', 6, current_timestamp, current_timestamp)" }

Pretty complicated, but it does the job :) Now we keep getting deprecation warning because :conditions, :insert_sql, :finder_sql are all deprecated and essentially removed in rails 4.1+. I kept postponing because it seemed like really hard to translate. But one suggestion in the error-message is to use has_many :through instead.

We already had the following statement in our Person model:

  has_many :person_relations

so for a simple linked model, we could just write

  has_many :parcels, through: :person_relations, source: :personifiable, source_type: 'Parcel'

and likewise, for our contacts, we just have to add a condition, but on PersonRelation, so we write:

  has_many :contacts,
           -> { where("person_relations.person_relation_type_id" => PersonRelationType::CONTACT)},
           through: :person_relations,
           class_name: "Person",
           source: :personifiable,
           source_type: 'Person'

I am not really happy with the explicit mention of person_relations in the condition, this might impact chainability later on, but I am not sure how I could handle that differently. For now this does the job really cleanly.

Now the problem is how to follow the reverse association (from the contacts to the organisations), and actually this also proves pretty simple. If I “reverse” the person-relations first, than we can use that as the through table:

  has_many :reverse_person_relations, as: :personifiable, class_name: 'PersonRelation'
  has_many :organisations,
            -> { where("person_relations.person_relation_type_id" => PersonRelationType::CONTACT)},
           through: :reverse_person_relations,
           class_name: "Person",
           source: :person

At first I felt that the deprecation of :insert_sql, :delete_sql, :finder_sql would be an insurmountable hurdle, but actually it proved pretty simple to fix and in the end a lot easier and even more readable. Nice :+1: