Tigraine

Daniel Hoelbling-Inzko talks about programming

Explicit path helpers with STI in Rails

I am currently working on an application that makes use of Single-Table-Inheritance (STI) for some of it's models.

STI in Rails is quite simple, you simply subclass a model and add the type column to your table like this:

And the accompanying migration:

Now that that's out of the way, Rails url helpers will automagically use the right route depending on the class you feed to it's helpers. Here's an example:

You get the idea, rails helpers are smart about this. Only problem: How about the cases where you need an explicit helper like edit_person_path?

This is where it get's tricky:

Using the explicit helper rails will not do any STI magic and simply return the path you asked for. What I really needed was for a helper that points to /persons/:id/edit in case it's a Person record and to /students/:id/edit for students. After some digging (Rails STI isn't really the hottest topic on Google it seems) I found the polymorphic_path method that does exactly this:

Filed under rails, rails-2, ruby, ruby-2

Removing delete and destroy in Rails models

Today I had an interesting feature request to implement: Get rid of all deletions and replace them with a deleted flag in the DB.

It's the usual story: Nobody really does deletes but rather everything is put into the DB in case it's needed at some later point. Unfortunately I didn't know about this particular feature until after I had finished most of the coding for the Rails application so going through the code and removing all destroy code from controllers was pretty much out of the question.

Instead I remembered reading about Modules in Ruby and how they can bolt on functionality to Classes.

Turns out it's totally trivial to remove deletion from Rails Models with 10 odd lines of code in a completely transparent an unobtrusive way:

module NotDeleteable
  def destroy
    unless self.respond_to? :deleted
      raise MissingMigrationException
    end

self.update_attribute :deleted, true end

def delete self.destroy end

def self.included(base) base.class_eval do default_scope where( :deleted => false ) end end end

class MissingMigrationException < Exception def message "Model is lacking the deleted boolean field for NotDeleteable to work" end end

This will override the default destroy/delete method provided by ActiveRecord::Base and also install a default_scope into the Model class so Rails will by default append WHERE deleted = false to all SQL queries made through the ActiveRecord Query Interface

You use this by simply including this module inside your Model class:

class User < ActiveRecord::Base
  include NotDeleteable
end
Did I mention that I really like Ruby?

Word of warning: I have no clue if I am breaking :dependant => :destroy on ActiveRecord relations in any way, but I suspect it should still be alright.

Update: The original code had an issue where you could not mark a record that is invalid as deleted. This was due to the fact that I was using save instead of update_attribute.

Filed under programmierung, rails, ruby

Rails .to_json nested includes and methods

Defining assocations to be included in the rendered Json in Rails is pretty easy. You just use the options hash to define an include in to_json and by voodoo magic to_json will also traverse the ActiveRecord assocation and render the associated entity as a nested element in the Json. The code in question is quite simple:

@object.to_json({:include => :assocation_a})

By default Rails will only include attributes in to_json so if you want to also serialize the return value from a method (for example if you want to concatenate some attributes or compute something) you can do so through the options hash:

@object.to_json({:methods => :my_method})

You can also combine them easily if needed:

@object.to_json({:include => :assocation_a, :methods => :my_method})

But this calls the my_method on @object. How do you tell to_json to invoke my_method on @object.assocation_a?

Not trivial, but it works:

@object.to_json({:include => { :assocation_a => { :methods => :my_method }})

It gets spicy when you already had multiple includes in an array like this:

@object.to_json {:include => [ :assocation_a, :assocation_b ]} 

And now you only want to include my_method in assocation_a and not assocation b. simply replacing :assocation_a by a hash like before isn't going to work. It took me some time but this is what I came up with:

@object.to_json {:include => { :assocation_a => { :methods => :my_method }, :assocation_b => {} }} 

Did I mention that I am amazed by how flexible the syntax is here?

Filed under programmierung, rails, ruby

Invoking rails i18n.translate with pluralization

One very nice thing about the internationalization library in Rails is it's support for pluralization by default. Instead of having to figure out how to display a plural or a singular when selecting what message translation you display you can just call translate and it will figure out if the plural or the singular form should be used.

Defining the two forms is done inside your config/locale/.yml like this:

found:
  one: "Found one result"
  other: "Found %{count} results"

This works out of the box for things like validation errors or ActiveRecord models. But it refused to work on me for my own little custom array I was outputting.

Turns out I was just not calling it correctly. I18n.translate simply takes a hash of options - expecting one of these options to be count so it can perform the pluralization check (by default this is entry[count == 1 ? 0 : 1]).

So in order to use this with a custom array you need to write something like this:

I18n.translate :found, :count => myarray.length

Since this allows you to pass any value you want through the arguments hash you can easily construct translations like this:

found:
  one: We could not find anything matching your query %{query}
  other: We found %{count} items

I18n.translate :found, :count => myarray.length, :query => "your query"

Filed under programmierung, rails, ruby

Securely managing database.yml when deploying with Capistrano

The more I venture into Ruby land the more magic Unicorns I find on the way. The wonders of SSH still seem totally outlandish to someone used to do deployments by RDPing into a server and xcopying a directory structure into your IIS folder.

But here I am and learning the ways of Capistrano and how deployments to multiple servers really should work.

Naturally I ran into issues I'll detail a bit later, but one of my major problems with my Rails deployment was the different database.yml between my production and my dev environment. Since the repository is in a shared location I could not put the production server mysql password into the config as it would be available to anyone with read access to the repository. This may be something you can get away with in a corporate environment, but if you plan on ever open-sourcing your project you should make sure you don't put production passwords into your repository :).

My solution to that problem is quite simple: I ssh'd into my server and put a "production" database.yml into the home directory of my deployment user and added the following task to my Capfile:

namespace :db do
  task :db_config, :except => { :no_release => true }, :role => :app do
    run "cp -f ~/database.yml #{release_path}/config/database.yml"
  end
end

after "deploy:finalize_update", "db:db_config"

The after statement tells Capistrano to run the db_config task right before finishing the code update, but before running any migrations in case you run cap deploy:migrations (capistrano process). And during every deployment I overwrite the database.yml from the repo with the one on the server.

I also added a assets:precompile task since Capistrano won't run the precompilation of Rails assets out of the box (you need RVM integration for this though):

  task :precompile, :role => :app do
    run "cd #{release_path}/ && rake assets:precompile"
  end
after "deploy:finalize_update", "deploy:precompile"

Et voilá: I can now run cap deploy:migrations from my dev machine and it will automatically connect to my release server, pull the code out of the git repository, compile the assets and migrate the database to a new version. And it will even roll-back to the old version if something goes wrong along the way.

Ps: I also struggled at one point with the SSH keys for the git repository. Since the deployment user on the server has no own private key I was inclined to generate one and add it to my git server's allowed keys list. But that's apparently the wrong way to go about things. The right thing to do here is to simply enable agent forwarding so the server will forward any questions about keys to your dev machine that should have the appropriate set of keys available.

ssh_options[:forward_agent] = true

Filed under rails, ruby, tools

The right thing to do: Rails deployment on Passenger

Today I deployed my very first Ruby on Rails application to a production server and failed. And I didn't fail so much because Rails is hard to deploy (the opposite is true) - but rather because Rails prevented me from doing something stupid!

But I digress, let's start at the beginning: I already wrote about my server setup last week and today was the time to deploy a Rails3 application to my Apache/Passenger.

The Passenger documentation really made things easy. I just cloned my repository to a folder and setup everything accordingly. Then I did the obvious chown -R www-data:www-data . so the www-data user Apache uses has full access to the whole application directory and fired up my browser.

And it didn't work. Passenger was obviously running as I was able to load files from the /public folder without a problem, but the routes inside my application only returned errorcode 500.

Why? Simple: Passenger by default assumes you are running in a production environment so it will load that up from your database.yml. So I had to make sure that those settings where correct (easy one). Next problem on the list was that any rake commands you are running on the server still assume you are using the development environment. So in order to create your databases and migrate the schema you have to do a:

  rake db:create RAILS_ENV="production"
  rake db:migrate RAILS_ENV="production"

Otherwise db:create and db:migrate will always run against the development environment settings inside database.yml.

But once that problem was solved, I was still getting 500s.. So I opened the /log/production.log and found another gem I really liked: Rails refused to start at all because I was running in production without having precompiled the assets (javascript/css)!

A simple rake assets:precompile fixed that, but boy was I impressed. I knew about the different environments in Rails and saw how they would affect deployment scenarios. But having Rails just throw exceptions at me if I try to do something so obviously stupid as to not have JavaScript and CSS minified and merged together into one file is really awesome. Especially when coming from a .NET environment where up to this date the <= .. => syntax does not safely URL-Encode the value (and it took them 10 years to release the safe <: ..> alternative, having a framework that throws you into the pit of success is exhilarating.

Filed under programmierung, rails, ruby

What I&apos;ve been up to

I just noticed that I started a new job almost half a year ago and didn’t mention it on my blog.

So it’s probably time I share what interesting stuff I’ve been doing lately.

New job

I now work for Life a software development company in Klagenfurt that’s situated inside the Lakeside Park. We focus on R&D in areas like ERP systems, natural language processing and other business solutions.

Although I still believe Lakeside Park is one of the ugliest buildings ever designed, from the inside it’s not that bad. It’s also located right next to the University, so I can attend courses in between work (a huge plus).

While I am mainly developing a CQRS-style business application I also did a lot of smaller projects for customers like WWF/AI.

CQRS

CQRS is a new architectural style coined by Greg Young that makes use of a few older patterns like Event Sourcing and CommandQuerySeparation as described by Fowler and Meyer. The style has been around for some time in the .NET space and Greg Young did a wonderful job of explaining it in a lot of screencasts and documentation he put up on his CQRS site.

The main idea behind CQRS is an eventually consistent architecture that does not rely on a big entity-relationship datamodel but rather on EventSourcing. EventSourcing means that you are storing every state transition inside your Domain as a distinct business event. So any model can be generated off this string of events that represents the currenct state. The benefit is rather huge because you can use heavily de-normalized models to read data from, while always issuing well-defined commands to mutate state.

I’ll blog on this in the future, but I strongly urge you to read up on cqrsinfo.com.

Still, it’s not an easy style to grasp and I had to let it sink for a few months before I could make heads or tails of it. In essence it’s so simple that you can explain it rather quickly, but it requires a pretty fundamental shift away from the CRUD style architecture you might be used to and finding out how to effectively work with this new “style” while being productive doing it takes some time.

Fortunately, just when I started to get into the right mindset for this way of working a project came in that required almost exactly the kind of traceability and flexibility Event Sourcing would give us, so I decided to go with a full CQRS stack.

CQRS in itself has worked out quite nicely so far. There is a lot of infrastructure I had to create, although fortunately Jonathan Oliver has created the EventStore project that at least spared me the work of rolling my own EventStorage system.

Since I’ll be working on this project for the rest of the year you can expect a few posts on the internals of the system and my thoughts on CQRS and eventual consistency in web applications.

JavaScript

Although I hate to admit it, I was always a web developer. I still suck at design as much as anyone else, but I was writing web applications all along, trying to convince myself that I was doing back-end stuff while hacking together the occasional HTML input form.

No more, I finally gave in and acknowledged the browser as the one platform I am probably targetting 80% of my work for, so I decided it’s time man up and really learn JavaScript.

I kind of knew JavaScript, it’s C based after all.. And I kind of knew my way around jQuery but never took the time to properly learn what makes this language so great.

So I got myself the brilliant book JavaScript: The Good Parts by Douglas Crockford and took a few nights to watch his great presentation Crockford on JavaScript that made a lot of things about the language clearer.

Funny thing: Right after I started getting a firm grasp around JavaScripts/EcmaScripts quirkyness I had to help out getting a project out the door that was entirely done in JavaScript as it was using the Sencha Touch JavaScript library to run on the iPad. (Note: ExtJS/Sencha are really incredibly ugly JavaScript frameworks – Use jQuery whereever possible)

Ruby and Rails

This goes hand in hand with the last point. After realizing that I’ll be doing MVC for a pretty long time I decided it’s time to really take another look at Rails and how it’s been doing while I was following ASP.NET MVC.

While I had looked at Rails earlier, I usually had given up trying to figure out how to install it on Windows and had just looked at the samples to conclude: “Same as .NET but with a bit of code-gen”

And oh boy was I wrong! While ASP.NET MVC really manages to get a lot of things right (at least for a MS framework), Rails3 is simply lightyears ahead.

And it’s not so much the core functionality I was usually looking at. It’s the subtle little things you don’t see in the samples but really learn to appreciate while working.

It’s the empty folders everywhere that give your code a very clean structure. Everything has it’s place.

And it’s the simplicity of it’s helper methods and little things like respond_to that are so incredibly hard and noisy to do in .NET land. Or the way helpers simply work whereas helpers in MVC usually make me want to tear my hair out (at least if you are working with dynamic models they simply fail).

Or another example of things that are simply there and nobody managed to get off the ground in 3 versions of .NET MVC is the asset bundling that’s been going on in Rails forever. Rails bundles all your javascript assets into one application.js file together to reduce browser load times, while .NET in MVC3 still references 2 seperate javascript library files in it’s default project template.

Rails is doing all the things right that I’ve been struggling with on the ASP.NET MVC platform for years whenever I was writing a simple business app, and it’s damn elegant all the way. It’s solving the CRUD application part so perfectly and with such simplicity that I am pretty sure I’ll be doing a lot of simpler applications in Rails in the future.

Vim and Visual Studio

Part of working with a lot of JavaScript is that you start to feel the limitations of Visual Studio as a JavaScript IDE. It’s simply inadequate and besides some syntax highlighting the whole editor simply falls down when writing JavaScript (not to mention the indentation screwups it does all the time).

So I ended up learning Vim and must say that I really enjoy it.

With the right plugins Vim is one hell of a powerful editor that does not require 600 mb of Ram and 40+ seconds to start up.

Having you editor boot in milliseconds instead of seconds has also had a huge impact on my work, and I have to say it annoys me every day when VS decides to hang up on me for 15 seconds only because I did hit save twice.

New home and cute mammals

I heard conclusive evidence that all blogposts are better with pictures of little furry mammals, so this one has to have them too.

To make that happen I moved into a new apartment with my Girlfriend and got myself two little baby cats that are called “Schrödinger” and “Marie Curie”.

Schrödinger:

schroedinger

Marie Curie:

curie

Restful-Authentication on Rails 3.1 RC1

While working on a small side project I decided to go with the bleeding edge and use Rails 3.1 RC1. One issue I ran into with this though is that they changed the generator scripts so the most instructions for the restful-authentication plugin didn’t work.

First of all the original plugin isn’t yet working on Rails 3 so there is a fork by vinsol that you can use instead.

After running: rails generate authenticated user session I did try to load /signup and was greeted by the following error:

uninitialized constant ApplicationController::AuthenticatedSystem

Looking throuhg sessions_controller.rb and users_controller.rb i found that both include AuthenticatedSystem with instructions to move that into application_controller.rb

Doing so unfortunately doesn’t work out of the box since rails apparently changed search-paths for libs so make sure to include the following in your application_controller.rb:

require File.join(Rails.root, 'lib', 'authenticated_system.rb')
include AuthenticatedSystem

At first I only tried require, but as it turns out require only loads a file and executes it (like include does in C) while include actually copies methods from another module to the current one.

Both are required for restful-authentication to work obviously, or your sessions_controller will throw errors like this one: undefined method `logout_keeping_session!' for #<UsersController:0x8fc409c>.

Hope this helps, it took me some time to figure this out, but I guess this is mostly because I am a total stranger to the Rails platform.

Filed under programmierung, rails, ruby

Sinatra vs WCF WebAPI

Yesterday I decided that there has to be a better way to expose data through JSon than to spin up MVC applications and abuse it to write a JSon returning service.

Since I was listening to Glenn Block on Hanselminutes talk about the WCF WebAPI I decided to give it a try and followed the hello-world article on codeplex to see what all the fuss is about.

It took about an hour to make the example work on my machine, and I completely failed in returning a clr-object as JSon. So after two hours of trying I gave up and decided to go to bed.

Today I had a few minutes of free time so I decided to have a look at Sinatra. 35 seconds later and I had a working “Hello World” running on my machine, with no configuration in 4 lines of code!

I then spent another 2 minutes figuring out how to return JSon from Sinatra (another 2 lines of code) and then decided to write this blog post.

Even though WebAPI is still a work-in-progress (that’s why it took so long to figure stuff out), it’s obcene that a WCF WebAPI “Hello World” requires more lines in web.config than Sinatra requires to do the whole sample.

In Sinatra the WCF sample literally boils down to these 10 lines:

require 'sinatra'
people = []
get "/hello/" do
	"Hello #{people.join(", ")}"
end
post "/hello/:person" do
	people << params[:person]
end

It’s tragic that you need to reference 6 .NET assemblies to achieve the things other platforms can do in 10 lines of code.. And the ruby code is also cleaner.

Filed under net, programmierung, ruby

Redmine extensions

I may have just hit an all-time-low in lines-of-code per hour, but it was fun nonetheless, so I thought I’d share this with you:

A customer had the crazy requirement for his Redmine Ticketing system that users can enter their email address to a ticket and be notified alongside the user that is associated with the user account. (This also means that many users are sharing one user to create Tickets in the System)

The solution was quite simple in the end, but getting there for a total stranger to Rails was a bit challenging.

First I created a custom field in Redmine that is required on all tickets and contains the email address the email should be sent to.

Next I went into app/models/issue.rb and changed the recipients method like this:

# Returns the mail adresses of users that should be notified def recipients notified = project.notified_users # Author and assignee are always notified unless they have been locked notified << author if author && author.active? notified << assigned_to if assigned_to && assigned_to.active? notified.uniq! # Remove users that can not view the issue notified.reject! {|user| !visible?(user)} notified.collect(&:mail) << custom_field_values end

As you can see, all it took was to append the custom_field_values (assuming there is only one custom field!) to the list of emails that should be notified. Once that was done I just had to restart the ruby server and it worked.

If this looks hacky to you: It is. But the requirements didn’t really warrant any more work to be put into this.

Finally: Ruby is a fun language to work with, although it’s also rather hard to understand a complex project like Redmine if you are looking at it without any prior ruby knowledge.

What really got me in the beginning was that ruby has no return statement. Quite simply the last statement of a function is returned to it’s caller. If you don’t know that about the language, trying to understand what a function does get quite challenging :)

Filed under programmierung, rails, ruby

My Photography business

Projects

dynamic css for .NET

Archives

more