Code for Concinnity

beautiful and elegant solutions


Restoring elegance to CakePHP — doing multiple joins The Right Way™

In my last article about unit testing, I mentioned one way to do ad-hoc multiple joins in CakePHP rather succinctly. Here’s a recap:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function tagged($tag)
{
    $this->bindModel(array('hasOne'=>array(
        'PostsTag'=>array(
            'foreignKey'=>false,
            'conditions'=>"PostsTag.post_id = Post.id"
        ),

        'Tag'=>array(
            'foreignKey'=>false,
            'conditions'=>"PostsTag.tag_id = Tag.id"
        )
    )));

    return $this->find('all', array('conditions'=>array(
        'Tag.name'=>$tag)));
}

This is, of course, rather unintuitive. A hasOne relationship when in fact I’m trying to look for someone hasAndBelongsToMany? I thought more about it.

There is a Bakery article that talked about doing ad-hoc joins. It looks more technically correct but just too freaking much verbose for my liking:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
    $markers = $this->Marker->find('all', array('joins' => array(
        array(
            'table' => 'markers_tags',
            'alias' => 'MarkersTag',
            'type' => 'inner',
            'foreignKey' => false,
            'conditions'=> array('MarkersTag.marker_id = Marker.id')
        ),
        array(
            'table' => 'tags',
            'alias' => 'Tag',
            'type' => 'inner',
            'foreignKey' => false,
            'conditions'=> array(
                'Tag.id = MarkersTag.tag_id',
                'Tag.tag' => explode(' ', $this->params['url']['q'])
            )
        )
    )));
?>

Actually, a simple refactoring can make it (almost) syntactically sweet and technically more correct:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
// /app/vendors/joins.php

/**
 * A new helper class to produce those join arrays just to make
 * life less miserable
 */

class Joins
{
    public static function left($model, $conditions)
    {
        return self::_makeJoin($model, $conditions, 'left');
    }

    public static function inner($model, $conditions)
    {
        return self::_makeJoin($model, $conditions, 'inner');
    }

    private static function _makeJoin($model, $conditions, $type)
    {
        return array(
            'table'=>Inflector::tableize($model),
            'alias'=>$model,
            'type'=>$type,
            'foreignKey'=>false,
            'conditions'=>$conditions
        );
    }
}

// /app/app_model.php

App::import('Vendor', 'joins');

class AppModel extends Model
{
    // ...
}

// /app/models/post.php

function tagged($tag)
{
    /*
     * Let's make use of our new class, this has become
     * a "one-liner."
     */

    return $this->find('all', array(
        'conditions'=>array('Tag.name'=>$tag),
        'joins'=>array(
            Joins::inner('PostsTag', 'PostsTag.post_id = Post.id'),
            Joins::inner('Tag', "PostsTag.tag_id = Tag.id")
        )
    ));
}
Published by kizzx2, on July 8th, 2010 at 8:30 pm. Filled under: CakePHP Tags: , , , No Comments

Ruby on Rails vs Django

The contest between the flagship MVC frameworks of the two of the best breed programming languages out there. Django is very interesting to study because it takes quite different approaches from that of Rails, and is probably one of the very few frameworks that isn’t a Rails clone.

1-minute summary

This funny piece kind of sums it up:

  • Person 1: “What do you do for a living?”
  • Person 2: “I work with computers.”
  • Person 1: “So do I! What do you do with computers?”
  • Person 2: “I’m a Web developer.”
  • Person 1: “So am I! Design, client-side programming or server-side programming?”
  • Person 2: “Server-side programming.”
  • Person 1: “Same here! Do you use dynamically typed languages or statically typed languages?”
  • Person 2: “Dynamically typed languages.”
  • Person 1: “So do I! Do you use a Web framework, or do you roll things on your own?”
  • Person 2: “I use a Web framework.”
  • Person 1: “So do I! Django or Rails?”
  • Person 2: “Django.”
  • Person 1: “Die, heretic scum!”

Opinionated, original opinions

  • The Django guys seem to be more pragmatic. They would say “maybe it’s too much magic for experienced programmers,” where the Rails folks would day “Look! It’s magic! The meta-programming is just elegant!”
  • The Django people wrote the official manual. Rails still don’t have many serious documentations at this point other than screencasts and RDoc. Understandable when DHH’s too busy participated in flame wars lol
  • Is it a co-incident that most resources I found regarding Rails vs Django are hosted on the Django’s Web site?

OK, those were focused on the communities more than the frameworks themselves. Heck, I said I was opinionated!

Something about the languages

A comment from a blog post: Why I moved from Ruby on Rails to Python/Django and back kind of ties up the Ruby vs Python issues quite nicely, and neutrally:

The fact that you need to be slightly more explicit in Django is actually considered a feature, since that increases readability and ease of maintenance. I do agree though that while Python is a pleasant language to develop and maintain code in, Ruby seems to be more focused at being fun. It feels like it lets you be ‘clever’ with your code in a way that Python won’t allow. For better and for worse, I’d guess that part is quite much just a matter of taste.

Let’s see the gurus sort it out

We also have a video of SnakesAndRubies, where we see “Adrian Holovaty, one of the creators (plural) of the Django framework for Python, and David Heinemeier Hansson, the creator (singular) of Ruby on Rails framework” go into debate.

Finally, some hard-core papers

For those of you who like hard-facts, people have wrote formal reports using scientific methods:

Opinionated summary

Disclaimer: I have only read the stuffs above when I write these. I myself, at this point, is a Rails person. I haven’t written a single line in Django (definitely worth a try when I get the time :)

After some heavy-reading, I came to the conclusion that Rails is basically a DSL written for MVC framework, and a heavy-duty DSL indeed. Django, on the other hand, really feels like an MVC framework written in Python.

What that means, very generally, is that you’d see a lot more magic in Rails than in Django.

Published by kizzx2, on June 2nd, 2009 at 1:18 am. Filled under: Web Tags: , , , , , , , 2 Comments