Out Loud

Loudthinking Archive

Categories

clousure (1) KaaS (1) mysql (1) rails (1) ruby (3) sap (1) singleton (1) spinact (1) streaming (1) video (2)

Monday, August 30, 2010

Mysql COALESCE | very useful

Example: You have a relational model where one table serves as a lookup-table (tblDefault) with default values for another table (tblInstance). tblInstance contains NULL-values in the cells where defaults are to be retrieved from tblDefault. The following query will do the merging:

SELECT i.id, i.name, i.whatever,
COALESCE(i.specific1, d.default1) as val1,
COALESCE(i.specific2, d.default2) as val2
FROM tblInstance i
LEFT OUTER JOIN tblDefault d
ON i.foreignKey = d.primaryKey;

COALESCE selects the first non-null value of its arguments, and the left outer join makes sure all records from the left table are returned.

Oh, and whitespace matters in this case. Placing a space between COALESCE and ( produces a general syntax error.

Wednesday, June 9, 2010

cakePHP - Apache and mod_rewrite (and .htaccess) - making pretty URLs

While CakePHP is built to work with mod_rewrite out of the box–and usually does–we've noticed that a few users struggle with getting everything to play nicely on their systems.

Here are a few things you might try to get it running correctly. First look at your httpd.conf (Make sure you are editing the system httpd.conf rather than a user- or site-specific httpd.conf).

  1. Make sure that an .htaccess override is allowed and that AllowOverride is set to All for the correct DocumentRoot. You should see something similar to:

    #
    # Each directory to which Apache has access can be configured with respect
    # to which services and features are allowed and/or disabled in that
    # directory (and its subdirectories).
    #
    # First, we configure the "default" to be a very restrictive set of
    # features.
    #
    <Directory />
    Options FollowSymLinks
    AllowOverride All
    # Order deny,allow
    # Deny from all
    </Directory>
  2. Make sure you are loading up mod_rewrite correctly. You should see something like:

    LoadModule rewrite_module libexec/apache2/mod_rewrite.so

    In many systems these will be commented out (by being prepended with a #) by default, so you may just need to remove those leading # symbols.

    After you make changes, restart Apache to make sure the settings are active.

    Verify that you your .htaccess files are actually in the right directories. This can happen during copying because some operating systems treat files that start with '.' as hidden and therefore won't see them to copy.
  3. Make sure your copy of CakePHP is from the downloads section of the site or our GIT repository, and has been unpacked correctly by checking for .htaccess files.

    Cake root directory (needs to be copied to your document, this redirects everything to your Cake app):

    <IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteRule ^$ app/webroot/ [L]
    RewriteRule (.*) app/webroot/$1 [L]
    </IfModule>

    Cake app directory (will be copied to the top directory of your application by bake):

    <IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteRule ^$ webroot/ [L]
    RewriteRule (.*) webroot/$1 [L]
    </IfModule>

    Cake webroot directory (will be copied to your application's web root by bake):

     <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
    </IfModule>

    For many hosting services (GoDaddy, 1and1), your web server is actually being served from a user directory that already uses mod_rewrite. If you are installing CakePHP into a user directory (http://example.com/~username/cakephp/), or any other URL structure that already utilizes mod_rewrite, you'll need to add RewriteBase statements to the .htaccess files CakePHP uses (/.htaccess, /app/.htaccess, /app/webroot/.htaccess).

    This can be added to the same section with the RewriteEngine directive, so for example your webroot .htaccess file would look like:

    <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
    </IfModule>

    The details of those changes will depend on your setup, and can include additional things that are not Cake related. Please refer to Apache's online documentation for more information.

Cake PHP - Controller action visibility

You can also change the visibility of controller methods in CakePHP by prefixing controller method names with underscores. If a controller method has been prefixed with an underscore, the method will not be accessible directly from the web but is available for internal use. For example:

<?php
class NewsController extends AppController {

function latest() {
$this->_findNewArticles();
}

function _findNewArticles() {
//Logic to find latest news articles
}
}

?>

While the page http://www.example.com/news/latest/ would be accessible to the user as usual, someone trying to get to the page http://www.example.com/news/_findNewArticles/ would get an error, because the method is preceded with an underscore.

cakePHP - Model and Database Conventions

Model classnames are singular and CamelCased. Person, BigPerson, and ReallyBigPerson are all examples of conventional model names.

Table names corresponding to CakePHP models are plural and underscored. The underlying tables for the above mentioned models would be people, big_people, and really_big_people, respectively.

You can use the utility library "Inflector" to check the singular/plural of words. See the Inflector documentation for more information.

Field names with two or more words are underscored like, first_name.

Foreign keys in hasMany, belongsTo or hasOne relationships are recognized by default as the (singular) name of the related table followed by _id. So if a Baker hasMany Cake, the cakes table will refer to the bakers table via a baker_id foreign key. For a multiple worded table like category_types, the foreign key would be category_type_id.

Join tables, used in hasAndBelongsToMany (HABTM) relationships between models should be named after the model tables they will join in alphabetical order (apples_zebras rather than zebras_apples).

All tables with which CakePHP models interact (with the exception of join tables), require a singular primary key to uniquely identify each row. If you wish to model a table which does not have a single-field primary key, such as the rows of your posts_tags join table, CakePHP's convention is that a single-field primary key is added to the table.

CakePHP does not support composite primary keys. If you want to directly manipulate your join table data, use direct query calls or add a primary key to act on it as a normal model. E.g.:

CREATE TABLE posts_tags (
id INT(10) NOT NULL AUTO_INCREMENT,
post_id INT(10) NOT NULL,
tag_id INT(10) NOT NULL,
PRIMARY KEY(id));

Rather than using an auto-increment key as the primary key, you may also use char(36). Cake will then use a unique 36 character uuid (String::uuid) whenever you save a new record using the Model::save method.

A Typical CakePHP Request

Flow diagram showing a typical CakePHP request


Black = required element, Gray = optional element, Blue = callback