For one of my projects I am using rails 4.1 (bleeding edge! yeah :) ) and suddenly noticed, that after opening my laptop in the morning my normal rails commands, like

$> rails c
$> rails g migration Bla name description some_more_fields

just … were hanging and nothing happened??? Like they were waiting for further input. Upon closer investigation, I assumed that the connection to the spring process was lost/corrupt (I move between networks a lot? maybe that could explain it).

For those unaware, as I was, spring is a Rails application preloader. It speeds up development by keeping your application running in the background so you don’t need to boot it every time you run a test, rake task or migration. Of course when that connection is lost, or corrupt, it hangs.

A simple

$> spring stop

stops the spring server, after which any rails command will restart it automatically. Fixed :)

Starting with ZURB Foundation 5, they use Bower to distribute the assets, and in their “getting started” guide they propose to install bower.

I have not yet installed bower myself, but there is a really easy alternative: use rails-assets.org.

At the top of your Gemfile add a source line:

source 'https://rubygems.org'
source 'https://rails-assets.org'  ## <---- add this line

and then add the gem

gem 'rails-assets-foundation'

In your application.js add

//= require foundation

And in your application.css add

*= require foundation 

Done! :)

According to oracle documentation, to change a value of a sequence, you have to drop and recreate it, using the following command:

CREATE SEQUENCE table_name_seq START WITH 12345;

But there are some easy ways to change the value of an existing sequence too.

If you want to increment the current value by 500, you can just use

select your_sequence_name.nextval from dual connect by level <= 500;

If you want to decrement it, you can do that as follows:

alter sequence id_sequence increment by -500;
select id_sequence.nextval from dual;
alter sequence id_sequence increment by 1;

(of course this can also be used to increment it, but the connect by level trick is easier then)

They default way in rails 4 to add foreign keys is simply

add_reference :people, :user

And this will add a column user_id to the people table, if the table exists. I have been looking in the rails code where this is handled, and it is really straightforward.

Note that standard rails does not really do anything for referential integrity, it creates the correct columns and an index if so specified.

But we use the schema_plus gem, for two reasons:

  • it does handle referential constraints correctly (on the database level)
  • it allows to specify the creation of views in a migration more cleanly

So, with schema_plus, if you write something like:

add_reference :people, :owner

and there is no owners table, this will give an error.

So instead you need to write :

add_reference :people, :owner, references: :users

This will correctly generate an owner_id which is a foreign key to users(id).

If you want to create a self-referential link, that is really easy. Just write

add_reference :people, :parent

This will create a self-referential link. Awesome :)

For completeness, the add_reference will add a reference columns to an already existing table. The same can be done when creating (or changing) a table with the following syntax:

create_table :people do |t| 
  t.references :owner, references: :users
  t.references :parent
end 

So, in short, if you were not using the schema_plus gem already, start doing so now :)

Gentle reminder, do not forget, in rails 4

rake assets:clean

seems to work, but actually does nothing. That is not entirely true: it only cleans the old assets, leaving the three most recent versions of the assets intact. So it is a like a mild cleaning, a throw-away-the-garbage-clean, a bring-those-old-clothes-you-never-wear-to-the-thriftstore-clean.

But sometimes that does not cut it. Sometimes, don’t ask me why, building my assets does not seem to work, my code is just not being picked up. And then you need to do use brute force cleaning (throw everything out). Run

rake assets:clobber

to actually clean the assets. The logic or meaning is lost on my me (clobber?), but this works.

For my current job we have two 2.3.5 rails sites, of which I already succesfully upgraded one to rails 4. For the other we still need to start the migration, and we were asked to install new windows servers to run the rails servers on in the meantime (let’s not digress why they choose windows, in a business environment Windows servers are still preferred, and let’s be honest; they are easier to maintain and manage then *nix servers at first sight).

So whatever: I had to install the rails 2.3.5 on a new Windows 2012 server.

This proved problematic, since the new ruby 1.8.7 comes with the new rubygems, and this does not work nicely with rails 2.3.5.

So step 1: install the old ruby 1.8.7 (p302), the old gems and run the rails server. This worked.

But then I saw this one thing I really needed to improve. So I migrated the project to the latest 1.8.7 and rails 2.3.18, use bundler for gem dependencies. On my development box this worked like a charm (Macbook Pro). So then I deployed this back on the server, and then the following happened:

C:/Ruby187/lib/ruby/1.8/pathname.rb:290:in `[]': no implicit conversion from nil to integer (TypeError)
    from C:/Ruby187/lib/ruby/1.8/pathname.rb:290:in `chop_basename'
    from C:/Ruby187/lib/ruby/1.8/pathname.rb:343:in `cleanpath_aggressive'
    from C:/Ruby187/lib/ruby/1.8/pathname.rb:331:in `cleanpath'
    from C:/Ruby187/lib/ruby/gems/1.8/gems/rails-2.3.18/lib/rails/rack/log_tailer.rb:9:in `initialize'
    from C:/Ruby187/lib/ruby/gems/1.8/gems/rack-1.1.6/lib/rack/builder.rb:54:in `new'
    from C:/Ruby187/lib/ruby/gems/1.8/gems/rack-1.1.6/lib/rack/builder.rb:54:in `use'
    from C:/Ruby187/lib/ruby/gems/1.8/gems/rack-1.1.6/lib/rack/builder.rb:73:in `call'
    from C:/Ruby187/lib/ruby/gems/1.8/gems/rack-1.1.6/lib/rack/builder.rb:73:in `to_app'
    from C:/Ruby187/lib/ruby/gems/1.8/gems/rack-1.1.6/lib/rack/builder.rb:71:in `inject'
    from C:/Ruby187/lib/ruby/gems/1.8/gems/rack-1.1.6/lib/rack/builder.rb:73:in `each'
    from C:/Ruby187/lib/ruby/gems/1.8/gems/rack-1.1.6/lib/rack/builder.rb:73:in `inject'
    from C:/Ruby187/lib/ruby/gems/1.8/gems/rack-1.1.6/lib/rack/builder.rb:73:in `to_app'
    from C:/Ruby187/lib/ruby/gems/1.8/gems/rails-2.3.18/lib/commands/server.rb:95
    from script/server:3:in `require'
    from script/server:3

What was going on here? Apparently in the rails/rack/logtailer.rb is the following code:

class LogTailer
  def initialize(app, log = nil)
    @app = app

    path = Pathname.new(log || "#{::File.expand_path(Rails.root)}/log/#{Rails.env}.log").cleanpath

And the cleanpath is somehow crashing. I tried googling this, to no avail.

Of course:

  • rails 2.3.18: who uses that still?
  • ruby 1.8.7 is deprecated
  • and deploying on windows servers

So I was on my own. I tracked the error down to the cleanpath_agressive which called the chop_basename recursively to remove superfluous . and .. redirections.

I am guessing the problem is that on windows, a path starts with a drive-letter, like D:\ or C:\ which messes up the ending of the cleanpath_aggressive loop.

Instead of really diving in, the path handed down to cleanpath in my case, did not need any cleaning, and furthermore, an uncleaned path would still work.

So I added an initializer config\cleanpath_bug_fix.rb with the following code:

if RUBY_PLATFORM =~ /mingw/
  # on windows the Pathname.cleanpath crashes on windows paths, instead of fixing it thoroughly
  # just ignore it
  class Pathname
    def cleanpath_aggressive
      self
    end
  end
end

Now my rails 2.3.18, using ruby 1.8.7p374 runs on Windows Server 2012R2. Woot ;)

I had this weird thing: it seemed, since my update to mavericks, that my macbook pro did not go to sleep anymore. Well, when on power supply, my computer never goes to sleep, but my display does.

I know that some applications, like full screen video, make sure that the screen does not go to sleep, even though I do nothing (luckily). So I went on a venture to see if I could find which application “hanged”.

Seems actually there is a really easy way to see that, in your console type

> pmset -g

And in my case the output look like this:

[system] ~/work/git/on_the_spot (master) > pmset -g
Active Profiles:
Battery Power       -1
AC Power        -1*
Currently in use:
 standbydelay         4200
 standby              1
 womp                 1
 halfdim              1
 hibernatefile        /var/vm/sleepimage
 darkwakes            1
 gpuswitch            2
 networkoversleep     0
 disksleep            10
 sleep                0 (sleep prevented by backupd)
 autopoweroffdelay    14400
 hibernatemode        3
 autopoweroff         1
 ttyskeepawake        1
 displaysleep         10 (display sleep prevented by Google Chrome)
 acwake               0
 lidwake              1

The important line: sleep prevented by Google Chrome, awesome, even I understand that :) So now the only thing I needed to do was go through my verrrry long list of tabs and check which one keeps the display from sleeping (I am an avid tab-collector). Apparently the screenhero homepage (screenhero seems like a very interesting option for remote pair programming, that’s why I kept it open) for some reason blocks the display from sleeping. Makes sense when it is in use, not so much on the homepage. Closed it, and shabam … fixed :)

When using SimpleCov in a very ill-covered project, I got amazingly good results: SimpleCov just did not count not-covered files. So files that were never used in our test-suite, were just simply being ignored. While I understand that approach, it did not feel good. I want to measure absolute progress, and I want to know how badly it really is.

So, on a mission to count all uncovered files with simplecov, I encountered an issue in their github repo. In itself it contained/mentioned two solutions:

  • in a three year old comment, a solution to set a starting base-line, and merge it after the tests. Unfortunately, it did not work completely: all files were added, but with complete coverage. Doh.
  • a pull request, claiming to fix it: while it did add all files, files that had before 100% coverage, where now no longer.

Let’s get technical. The first solution added a baseline, with for all lines the value nil. The second added the value 0 for each line. The value nil is what SimpleCov uses internally to count for a never line: a line that never matters. Which is either an empty line, a comment line, or begin and end of a class.

The zero is line that is not covered (a 1 is a line that was covered). When merging lines for files that had coverage, I assume the base-line 0 takes precedence over the coverage-calculated nil and so we end up with a non-covered line in the merged result. Bummer.

So I added my spec_helper.rb as follows:

if ENV["COVERAGE"]
  require 'simplecov'
  SimpleCov.start 'rails'
  SimpleCov.coverage_dir 'coverage/rspec'

  all_files = Dir['**/*.rb']
  base_result = {}
  all_files.each do |file|
    absolute = File::expand_path(file)
    lines = File.readlines(absolute, :encoding => 'UTF-8')
    base_result[absolute] = lines.map do |l|
      l.strip!
      l.empty? || l =~ /^end$/ || l[0] == '#' ? nil : 0
    end
  end

  SimpleCov.at_exit do
    coverage_result = Coverage.result
    covered_files = coverage_result.keys
    covered_files.each do |covered_file|
      base_result.delete(covered_file)
    end
    merged = SimpleCov::Result.new(coverage_result).original_result.merge_resultset(base_result)
    result = SimpleCov::Result.new(merged)
    result.format!
  end
end

So, before the test runs, I create a “baseline” containing for all possible ruby files (might need to filter that later), a nil if the line is empty or the “ending end” of a file, and a zero otherwise. After the tests have run, I remove the covered files from the “baseline”, and those are then merged with the result that get the final result.

Now maybe try to translate that into a pull request :)

I develop my website using a MacBook Pro retina, and deploy on windows. And I noticed that my Macbook Pro is a lot faster than the standard GeoServer install. I use Geoserver only to serve the WMS layers, vector data which is stored in postgis.

So I needed to tune GeoServer on Windows for optimal performance. I googled around, and found I needed to make the following changes:

  • make sure jvm runs in -server mode
  • make sure jvm is allocated enough memory
  • optimise jvm settings
  • install native JAI/ImageIO binaries
  • switch to production logging

I used the standard Geoserver binary install, so to tune the jvm settings, you have to edit c:\program files\Geoserver xxx\wrapper\wrapper.conf and add the following lines:

# Java Additional Parameters
wrapper.java.additional.1=-Djetty.home=.
wrapper.java.additional.2=-DGEOSERVER_DATA_DIR="%GEOSERVER_DATA_DIR%"
wrapper.java.additional.3=-server 
wrapper.java.additional.4=-Xmx2048M -Xms2048m 
wrapper.java.additional.5=-XX:SoftRefLRUPolicyMSPerMB=36000 
wrapper.java.additional.6=-XX:MaxPermSize=128m 
wrapper.java.additional.7=-XX:NewRatio=2 

to be able to run the jvm in server mode, I had to copy $JAVA_HOME\bin\client to $JAVA_HOME\bin\server which feels like an awesome hack.

But Geoserver does seem a lot quicker.

I read the wms shootout benchmarks (2011) and one of the results showed that MapServer was a lot quicker on linux (vs. windows).

So that has got me wondering though, what possible other things I could do to improve performance.

E.g.

  • deploy geoserver on linux vs windows?
  • switch containers: jetty vs tomcat vs jboss, or doesn’t that make much of a difference?
  • or how hard would it be to switch to a “quicker” wms, e.g. mapnik/mapserver

So since none of this questions I can find answered somewhere on the web (at least not easily, and i asked), I will probably be doing some benchmarks for myself soon.

I am currently converting my GIS application that needs two browser windows (one for the map, and one for the administrative data and functions), to a single window application using the netzke gems (which in turn rely on Sencha Ext js).

The netzke gems are extremely powerful, but there is a bit of learning curve for me, since both netzke and ext js are new. But netzke makes a lot of things a lot easier. It is not really rails-like, since it abstracts a lot away, and I am not yet completely convinced of the approach. But for my current goals it is ok.

I have a panel containing an openlayers map, and a toolbar with action buttons. The action buttons need to indicate state (drawing/measuring). So when clicked they have to be in a “pressed” state, and start with the action.

Although I found no example of this, achieving it was pretty easy. I defined my action buttons as follows:

action :measure_line do |c|
  c.id = "measure_line"
  c.icon = :ruler
  c.text = ""
end

action :measure_area do |c|
  c.id = "measure_area"
  c.icon = :surface
  c.text = ""
end

js_configure do |c|
  c.layout = :fit
  c.mixin
end

def configure(c)
  c.desc = "Contains the openlayers map"
  c.title = "Map"
  c.tbar = [:draw_point, :draw_line, :draw_polygon, :measure_line, :measure_area, :navigation_history]
  c.body_padding = 5
end   

I am only showing the actions for :measure_line and :measure_area because these are now the relevant ones I want to show. I need to give explicit id to the buttons, so that I can use Ext.ComponentManager.get to find them later on.

Nice thing to know is that the action handler by default receives the pressed button (yes!). This will allow us to just toggle it. So your mixed in javascript will look this:

{
    onMeasureLine: function(btn) {
      Map.toggleMeasuring(btn, 'line');
    },
    onMeasureArea: function(btn) {
      Map.toggleMeasuring(btn, 'polygon');
    },
}

Because I prefer to write coffeescript (not found how I can do that for the netzke mixins), I have a class Map in map.js.coffee containing all map-related functions. toggleMeasuring needs the button and the measurement-action to activate/deactivate

toggleMeasuring: (button, measurement_type) ->
  button.toggle()
  if 'pressed' in button.uiCls
    @measureControls[measurement_type].activate()
  else
    @measureControls[measurement_type].deactivate()

  # make sure the other measuring is automatically switched off
  for  key of @measureControls
    unless key == measurement_type
      @measureControls[key].deactivate()
      Ext.ComponentManager.get("measure_#{key}").toggle(false)

That is about the gist of it. I will be sharing more of my netzke experience and code soon. For the moment still impressed :)