Logic inside of Handlebars templates for Ember.js is possible, just not pretty

We had a few occasions where we needed something like count > 0 or other simple logic, that should live inside the template, but its impossible… until now 🙂

Code

{{#ifEval "this.getPath('content.click_count') >= 0"}}
   The content has been clicked {{content.click_count}} times!
{{/ifEval}}

Usage

Handlebars.registerHelper('ifEval', function(code, options) {
  if(eval(code)){
    return options.fn(this);
  }
});

Testing geolocation with capybara + selenium + firefox

Just built this little snippet in a hacknight, it simulates a geolcation via capybara, so you can test if you geo-magic actually works 🙂

View

<p>Finding your location... <span id="status">checking...</span></p>
<script>
  jQuery(function () {
    var timeout = (document.location.href.indexOf('test_location') >= 0 ? 100 : 0);

    setTimeout(function(){
      navigator.geolocation.getCurrentPosition(function(){
        jQuery('#status').html("found you!");
      });
    }, timeout)
  });
</script>

Capybara test via selenium in rspec

  def simulate_location(lat, lng)
    page.driver.browser.execute_script <<-JS
      window.navigator.geolocation.getCurrentPosition = function(success){
        var position = {"coords" : { "latitude": "#{lat}", "longitude": "#{lng}" }};
        success(position);
      }
    JS
  end

  it "can use location", :js => true do
    visit '/?test_location=true'
    simulate_location 20, 20
    sleep 0.2
    page.should have_content "found you!"
  end

Convertig a HABTM join table to a real activerecord model

If your has_and_belongs_to_many associations suddenly need to know more, its time to convert them to a real model.

  • rename table
  • add id
  • add created_at/updated_at as not-null (need to set existing records to something)

Code

class CreateJoinModel < ActiveRecord::Migration
  def change
    rename_table :products_users, :purchases
    add_column :purchases, :id, :primary_key
    [:created_at, :updated_at].each do |column|
      add_column :purchases, column, :timestamp, null: false, default: Time.at(0)
      change_column_default :purchases, column, nil
    end
  end
end

Resque test helpers, e.g. process all jobs

When testing resque jobs, the simples solution is to set Resque.inline = true, which just executes the jobs imediatly, but if you want to make sure that they e.g. have been scheduled for the right time or simulate non-parallel execution, you might find these useful.

ResqueScheduler
module ResqueScheduler
  def all_scheduled_jobs_count
    total_jobs = Hash.new(0)
    Array(redis.zrange(:delayed_queue_schedule, 0, -1)).each do |timestamp|
      total_jobs[timestamp.to_i] += redis.llen("delayed:#{timestamp}").to_i
    end
    total_jobs
  end
end

Resque
module Resque
  def self.perform_enqueue_and_scheduled(queue)
    while timestamp = Resque.next_delayed_timestamp
      Resque::Scheduler.enqueue_delayed_items_for_timestamp(timestamp)
    end
    Resque.perform_all(queue)
  end

  def self.perform_all(queue_name)
    until size(queue_name) == 0
      reserve(queue_name).perform
    end
  end
end