### Calculate next reporting date

It's been a while since my last post. I've been hacking along though. Here's an interesting puzzle I faced recently.

In the app, I have an model called Corporation. Each corporation has a reporting frequency, a start date and the timezone it's in. The task is to calculate the next (and the last) reporting date for each corporation. It seems pretty straight forward, but the devil is in the details ...

The trimmed down version of my implementation is below

``````class Corporation < ActiveRecord::Base

REPORTING_FREQUENCY = %w(monthly bi-monthly quarterly half-yearly yearly)
REPORTING_FREQUENCY_INCREMENTS = { 'monthly'     => 1.month,
'bi-monthly'  => 2.months,
'quarterly'   => 3.months,
'half-yearly' => 6.months,
'yearly'      => 12.months }

def next_reporting_date
now = Time.now.in_time_zone(time_zone).to_date

return start_date if start_date > now

reporting_date(now, start_date.day, start_date)
end

private

def reporting_date(now, original_start_day, start)
if original_start_day > start.day && start.end_of_month.day >= original_start_day
start = start + (original_start_day - start.day).days
end

return start if start >= now

reporting_date(now, original_start_day, start + reporting_frequency_increment_value)
end

def reporting_frequency_increment_value
REPORTING_FREQUENCY_INCREMENTS.fetch(reporting_frequency)
end

end
``````

The only tricky bit is the first `if` block inside the recursive `reporting_date` call. It makes sure we're not losing days when we cycle through months that have less days than the `start_date.day` value.

Hope I'm making sense here ... and I'm sure there are existing algorithms out there doing what I want more elegantly.

Published: 2013-03-28

### Change machine

Start of the year, some fun stuff.

I recently had some spare time and re-visited my first ever uni assignment. The problem it's trying to solve is easy, given any amount of money in cents, figure out the minimium number of coins required. No need to say, the little Java program I wrote was crazily bad. So I rewrote it again in Ruby.

And here's my solution after over 10 years of programming practice :)

``````module ChangeMachine

class IdiotEncountered < StandardError; end

AVAILABLE_UNITS = [10000, 5000, 2000, 1000, 500, 200, 100, 50, 20, 10, 5]

def self.show_me_the_money(dollar_in_cents)
raise IdiotEncountered, "You are an idiot, no such amount in AUS..." unless dollar_in_cents % 5 == 0
dispense(dollar_in_cents)
end

def self.dispense(dollar_in_cents)
return {} if dollar_in_cents == 0

unit = AVAILABLE_UNITS.select{|u| u <= dollar_in_cents}.max
{unit => (dollar_in_cents / unit)}.merge(dispense(dollar_in_cents % unit))
end
end

puts ChangeMachine.show_me_the_money(37500).inspect
# => {10000=>3, 5000=>1, 2000=>1, 500=>1}
``````

My Java version can be found here under the comments section.

Published: 2013-01-04

### PostgreSQL memory size

I'm making a fresh OSX installation. After installing PostgreSQL using homebrew, the service cannot startup intermittently. The PostgreSQL server log says

``````FATAL:  could not create shared memory segment: Cannot allocate memory
DETAIL:  Failed system call was shmget(key=5432001, size=3809280, 03600).
HINT:  This error usually means that PostgreSQL's request for a shared memory segment exceeded available memory or swap space, or exceeded your kernel's SHMALL parameter.  You can either reduce the request size or reconfigure the kernel with larger SHMALL.  To reduce the request size (currently 3809280 bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections.
``````

Straight forward stuff, modify or create `/etc/sysctl.conf` and toss in the following

``````kern.sysv.shmmax=16777216
kern.sysv.shmmin=1
kern.sysv.shmmni=32
kern.sysv.shmseg=8
kern.sysv.shmall=65536
``````

Apparently I have done this before from my previous OSX installations... Next time will be easier with this note jotted down here.

Published: 2012-11-10

### What makes a good framework

The other night, I watched Yehuda's talk, Ember.js, State of the Union. One thing Yehuda said strikes me. He briefly talked about framework's internal modularity and how a framework should be presented to developers.

There's no doubt a good framework needs to be modular, so that changes can be easily made and new features can be added in relatively easily. I see 2 types of modular framework out there.

1. Modular frameworks that are branded to be opinionated, a.k.a, Rails. Despite its modular internals, from the outside, you use the framework as instructed, no more, no less. Out of the box, it solves a typical type of problem. However once you become confident and efficient with it, you have the power to ride the Rails with your own way, thanks to its modularity.
2. Frameworks that are modular, and the framework provides the modules as building blocks. Things are then left to the devs to work out, a.k.a. Zend Framework. It's super flexible, but it's hard to figure out how to handle the beast. You need to do all the glue work yourself. Put the pieces together yourself. The steep learning curve often leads to mis-use, and yes that's talking from self-experience.

So what makes a good framework? Back to what Yehuda said, it's gotta be modular, with an easy and default way to interact with the framework. The framework needs to set sensible defaults out of the box.

Rails does this really well. Maybe one day I'll outgrow Rails, but for now, I can't be happier.

To back me up, just compare how Zend Framework and Rails handle building web forms (yes, that's what we do on the web all the time...)

What one is better? You are the judge!

Published: 2012-09-07

### Chrome's broken back button

Chrome is my primary browser because it's fast and minimal. One thing surprised me today is its (in)ability to deal with content caches.

The issue I encountered is this.

• I have a resource `myapp.com/my_resource`.
• I first load the page in with a request of content type text/html. The page itself has some Javascript, which will issue an Ajax request to the same URL `myapp.com/my_resource`. The Ajax request is requesting the same resource URL, but with a different content type, application/json.
• On the `my_resource` page, I click on another URL
• Once I'm on the new page, I hit the back button(I'm lying here, I press the `delete` key). Chrome dumps out all the JSON data returned by the Ajax request instead of rendering the previous "text/html" page content.

The reason is when Chrome caches content, it discards HTTP headers. This means as long as the resource URL is the same, the Ajax request's response automatically becomes the cache value for my `myapp.com/my_resource` URL. To me, this really breaks RESTful web apps' state management.

Problem is tricky, fix is easy. Just toss in a random number as a postfix to the Ajax request URL (well, it's not really a solution. The Ajax request will not get cached by the browser anymore...)

``````\$.getJSON "/my_resource?#{new Date().getTime()}", (data) ->
# blah blah
``````

## EDIT

Since I'm working on a Rails app, instead of hacking a timestamp to the Ajax URL, I can just make the URL `.json`

``````\$.getJSON "/my_resource.json", (data) ->
# blah blah
``````
Published: 2012-09-03

### ActiveRecord model responsibilities

While I'm drafting this post, I got pointed to this article, Fear Of The Class: Fat Model Kills Your Software Design, from a tweet. This article says 90% of the things I wanted to say here, so I'll not repeat those.

One extra thing I want to point out is some madness I faced in recent weeks. And of course, it relates to the AR model responsibilities topic.

In Rails land, I accept the fact we can call `to_json` on a AR model instance and pump the output back as a JSON response. I occasionally use it when I'm just prototyping something, but I seriously believe calling `to_json` on AR model is wrong. `to_json` simply isn't a responsibility to an AR model class. Handle it in the views with RABL, use a decorator/presenter, freedom is all yours!

As I dislike Rails giving all AR model `to_json` method, I'm hit by something much worse. In a central ORM lib at work, a recent change was made to automatically serialise boolean fields to JSON format upon data retrieval. So if someone needs just a true or false ... too bad, ORM gives back JSON true and JSON false, convert it back to boolean yourself!!! When I read and noticed the change, it was a WTF moment. When I questioned the change and told to go and read on it, I wave white flag ...

Published: 2012-08-24

### RSpec integration tests with custom headers

While writing an integration test, I needed to pass a custom HTTP header to the GET request. Doing a quick scan in the Rails source (I'm using Rails 3.1.3) points me to here.

It looks like all I need is to include my custom HTTP header in a hash and pass it to the `get` call as the last argument.

Fairly straight forward, I came up with this

``````get "/api/xxxxx/xxxxx/xxxxx",
{ format: "json" },
{ authorization: "Token token=\"#{app.token}\"" }
``````

As you can see, I trusted the doc, I used `authorization` as the header hash key. I was hoping it'll be turned into `HTTP_AUTHORIZATION`. And you can guess, it didn't, my request spec was failing badly, returning me HTTP 401 instead, not passing the initial authentication. It turned out that the Rails doc is lying to me. I had to fire the `get` call like this instead

``````get "/api/xxxxx/xxxxx/xxxxx",
{ format: "json" },
{ "HTTP_AUTHORIZATION" => "Token token=\"#{app.token}\"" }
``````
Published: 2012-07-23

### CKEditor and Rails

One reason I really enjoy working with Ruby/Rails is because of the Gems. When you want to integrate a Rails app with some 3rd party utilities, it's pretty likely that you can find existing Gems doing just that for you (80-20 rule here of course).

I need to integrate CKEditor with my Rails app. Guess what? There's a ckeditor gem for it! Just follow the VERY good readme to get it installed. For a Rails 3.2 app, you literally just need to add 2 lines or 3 lines of code to have it all set up ...

Add it to your `Gemfile`, and bundle install it

``````gem 'ckeditor', '3.7.1'
``````

If you want to handle uploads from the editor, stick the following into your `ruotes.rb`. I didn't do this myself, because I'm only after text editing.

``````mount Ckeditor::Engine => "/ckeditor"
``````

``````//= require ckeditor/init
``````

At this point, it's done and working (this is the 80% rule)! However for what I needed (the 20%), I did some customisation.

I'm using the awesome simple_form, so I created a little helper method in my `application_helper.rb`

``````def rich_text_editor(form, attr)
form.input(attr, as: :ckeditor, input_html: { class: 'string', customConfig: asset_path('ckeditor_config.js') }).html_safe
end
``````

As you can see, I load a custom `ckeditor_config.js`. It basically gives me a custom tool bar. Oh! Don't forget to add ckeditor_config.js to `config.assets.precompile` list in `application.rb`.

``````CKEDITOR.editorConfig = function( config )
{
config.toolbar = 'MyToolbar';

config.toolbar_MyToolbar =
[
['Bold', 'Italic','Underline', '-', 'NumberedList', 'BulletedList'],
['UIColor','TextColor','BGColor'],
['Maximize', 'ShowBlocks','-','Source'],
['Paste','PasteText','PasteFromWord','-','SpellChecker']
];
};
``````

Now, in any of my view files, I use the helper method like this

``````= simple_form_for @object do |f|
= rich_text_editor f, :description
``````

All good! Yes, all good on development... Deploy it to staging, it fails miserably. Why? Asset Pipeline again! For Heroku hosted apps (staging and production), I'm using an S3 `asset_host` for static assets. The CKEditor init script tries to load it from the app's domain instead...

After reading the ckeditor init script, it's very easy to fix! Rename the javascript manifest file to `application.js.erb`, so that we can use Ruby code. Make the manifest require self and add some voodoo to set the `CKEDITOR_BASEPATH`.

``````//= require_self
// ...
// your other requires, make sure require_self comes before requiring ckeditor/init
//= require ckeditor/init

(function() {
<% if Rails.env.production? %>
window['CKEDITOR_BASEPATH'] = "http://<%= ENV['FOG_DIRECTORY'] %>.s3.amazonaws.com" + "/assets/ckeditor/";
<% end %>
}).call(this);
``````

That's it! Why I use `ENV['FOG_DIRECTORY']` in the basepath? See my previous posts(1 and 2) for details.

Sweet, all good.

Published: 2012-07-15

### Heroku Deploy Bash Script

Quick and short one. The Heroku hosted app I'm working on has a staging env. I need to quickly deploy from local to the staging Heroku remote repo a lot. Doing `git push staging whateverbranch:master` is fine, but just tedious to type every time. And since the app is at early development stage, I need to constantly deploy to staging from a local feature branch to just do the show-n-tell, a simple bash/zsh alias will not do the job (well, I don't know, maybe it can ...).

So... since I'm using RVM and a project `.rvmrc` anyway, I throw the following function into my project `.rvmrc`. With that, I can just do `deploy staging`, job done!

``````deploy() {
local ref=\$(git symbolic-ref HEAD 2> /dev/null) || return

echo "Deploying to Heroku: "
echo "   - git push \$1 \$current_branch:master"
git push \$1 \$current_branch:master

echo "Running database migration: "
echo "   - heroku run rake db:migrate"
heroku run rake db:migrate
}
``````

It's quick and dirty, and once the app gets released I'm sure I'll come back to modify it or move the deployment into a Rake task. Working just fine for now!

Published: 2012-07-14

### Asset Pipeline with Heroku Continued

This is a follow up post to yesterday's article on how I work with asset pipeline for a Heroku hosted app.

While the setup described from the previous article works. It leaves a few sticking points.

1. Before I do assets precompile, I have to either `export` the necessary environment variables manually, or set them up in my .zshrc globally.
2. It's hard to precompile assets for different deployment targets, e.g. staging and production.
3. I have to remember to run the assets clean rake task to keep my local dev env sane.

So ... I did some follow up work. The README I wrote for the specific project is as follow.

## Asset Compiling

Assets are precompiled locally and automatically uploaded to S3 with the help from the asset_sync gem.

After step into the project root directory, simply calling a custom ap() function, such as

``````⚡ ap staging
``````

to compile the assets and upload the compiled assets to S3.

For this to work, RVM on local development machine is required. The handy function `ap()` is defined in `.rvmrc` under the project root.

The argument passed into the `ap()` function should be a valid Heroku Git remote name.

For example, we have staging setup on Heroku because of the following `git remote` output.

``````⚡ git remote -v
origin  git@bitbucket.org:xxxxx/xxxxx.git (fetch)
origin  git@bitbucket.org:xxxxx/xxxxx.git (push)
staging git@heroku.com:xxxxx.git (fetch)
staging git@heroku.com:xxxxx.git (push)
``````

This means we will need to create a `.projectrc.staging` file under the project root. A projectrc template is provided, `.projectrc.sample`. 3 config variables need to be filled in.

Note that `FOG_DIRECTORY` is the Amazon S3 bucket name. To mute `fog`'s noisy output during assets precompile, name the S3 bucket using only alphabets and `.` is recommended.

The same 3 variables are also set on Heroku and can be found by doing

``````⚡ heroku config
``````

The `ap()` function does the following

1. precompile assets locally
2. upload the compiled assets under `/public/assets` to the corresponding S3 buckets
3. purge local compiled assets from `/public/assets`, with the exception of `/public/assets/manifest.xml`, which is pushed to Heroku.

Now to finish it up, here's my .rvmrc

``````rvm ruby-1.9.2-p290@my_project --create

ap() {
local projectrc=".projectrc.\$1"

if [ -f "\$projectrc" ]; then
source "\$projectrc"

bundle exec rake assets:precompile
git commit -m 'updated asset manifest'
bundle exec rake assets:clean && git checkout public/assets/manifest.yml
else
echo "Missing '\$projectrc'. Check README for details."
fi
}
``````

And here's the .projectrc.sample

``````export FOG_DIRECTORY=XXXXXXXXXXXXX
export AWS_ACCESS_KEY_ID=XXXXXXXXXXXXX
export AWS_SECRET_ACCESS_KEY=XXXXXXXXXXXXX
``````

Hope this makes sense and helps.

Published: 2012-07-12