逆転の発想(データの取り出し方)

2007/04/18 | cakePHP

「hasAndBelongsToMany」。諸問題はあったがなんとか動くことが確認できた。しかし必要なデータを取り出す手法がわからなかった。
ブログの記事とタグの関係を例に出すとする。記事はたくさんあるし、タグもたくさんあり、両者の関係は「多」対「多」で表すことができる。モデルとしては「article(記事)」と「tag(タグ)」の二つを作るとする。
この条件で、特定のタグを持つ記事を抽出しようと試みた。記事を抽出したいのだから、articleモデル内でhasAndBelongsToManyの設定を記述し、articleコントローラでデータを取り出そうと試みた。しかしどのように記述しても記事は全部抽出されてしまう。それぞれの記事には関連するタグが割り付けられているので、特定のタグのあるなしで、どの記事が必要なのか、ということはわかるが、記事が全て抽出されてしまっているため、なんとも不細工な処理だ。
酒を飲みつつ、ふと思いついた。逆の発想、タグからたどればいいじゃない!。タグと記事は多対多で同等の関係にあるわけだから、逆から見ても同様にデータを取得できる。つまり特定のタグに紐付けられた記事を全て抽出できるわけだ。あとはfindメソッドで、特定のタグのみ抽出すれば、これで全て事足りる。目からうろこの処理だった。
お酒もたまにはいいことあるね。

hasAndBelongsToManyは少し厄介

2007/04/17 | cakePHP

リレーションのための「hasAndBelongsToMany」。これは少々厄介だ。かなりトラぶったのでメモしておく。
まずこのリレーションを使おうとすると、使用する環境に注意が必要だ。環境とはすなわち、MySQLのバージョンとcakePHPのバージョンだ。cakePHPのデフォルトの記述方法だとMySQL3.23.58ではエラーが発生する(要はMySQL4で記述せよ、ということ)。
まず状況の説明。最初はMySQL3.23.58とcakePHP1.1.13.4450な環境で動作させようと試みた。しかしどうやってもリレーション先のテーブルのデータを取ってこれない。そこでMySQL5な環境で試してみたが、それでもやっぱり動かない。
ここではたと気づいた、バグがあるのでは・・・。調べてみたら賢者はいました。すばらしい。
http://cl.pocari.org/2007-04-06-2.html

ちなみにうちではcakePHP1.1.13.4450ではエラーは出なかった。それにMySQL5でもうまくいかなかった(これはテスト不足なだけかもしれない)。そこでまずcakePHP1.1.14.4797(執筆時点の最新バージョン)にアップデート(cakePHPのアップデートは簡単で、cakeディレクトリ内のファイルをごっそり入れ替えるだけ)。そうすると出ました、エラーメッセージ。ここで上記サイトに記載があるように、以下のように修正。

cake/libs/model/datasources/dbo_source.phpの1050行目

「’alias’ => $joinAssoc,」の記述があるのでその下に以下の一行を追加。
「’type’ => ‘INNER’,」

これで見事に解決した。3時間近く悩んだだけに感慨もひとしお。しかし上記ページの作者曰く「上記の修正はあくまで,hasAndBelongsToMany を使いたい場合で,そのほかの項目はあまりテストしていませんのでご注意を.」とのこと。まぁ問題が出たらその都度対応することにしよう。
貴重な情報に感謝。

テーブルのリレーション

2007/04/16 | cakePHP

久しぶりにcakePHPに戻る。近頃は一からシステムを組むなんてことに対して完全に億劫になっている。CMSツールとしてブログを使えば大抵のことができるから。記事管理ツールをわざわざ作らなくても、カスタマイズだけでできちゃうからね。
しかし、それでもだめな場合がやはりある。そういう場合でも極力楽をしたいから、そんなときにはcakePHPというわけだ。
しかし如何せん、まだ慣れてない。現状は簡単な仕組みを組むのもマニュアル片手にやっている状況だ(それでもすこぶる使い勝手がいい)。業務ではmojaviとcakePHPのフレームワーク二本立てだけれど、徐々にcakePHPに移行中、というわけだ。
さて本題。cakePHPでテーブルのリレーションを定義する方法。cakePHPでは極力定められたルールに則ってスクリプトを書くことで、定義ファイルも書かなくていいし、SQLも書かなくていい。直にSQLを書く必要がないから、その代わりにテーブルのリレーションをスクリプト側で定義したやらなければならない(ちょっとだけ面倒)。定義の仕方は4種類。ちなみにリレーションの定義の前に、関係するテーブルのモデルは別途個別に作成しておく必要がある。

■hasOneとbelongsTo
基本的に「主」と「従」のテーブル中のレコードが一対一で結ばれる場合、「主」から見て「従」へのリレーションを作成する場合にhasOne、「従」から見て「主」へのリレーションを作成する場合にbelongsToと使う(厳密には違うような気がするけど大体これでいいと思う)。例えばユーザIDのテーブルと、そのユーザのプロパティを格納したテーブルであれば、ユーザIDのテーブルを「主」、プロパティのテーブルを「従」とみなすことができる。

■hasMany
こちらは「親」と「子」と表現するほうがよさそう。「親」テーブルのレコード1つに対して「子」テーブルの複数のレコードが該当するような感じ。1対多の関係になっているタイプ。

■hasAndBelongsToMany
これはちょっと複雑。例えば「人間」と「検索エンジン」というテーブルの組み合わせを考える。Aという人間はgoogleとyahooを使う。Bという人間はyahooとaskを使う。こういう具合に多対多のリレーションを考えるとき、間にもう一つテーブルを入れればわかりやすい。つまり関係を表すデータのみをもつテーブルだ。hasAndBelongsToManyはこういうテーブルをあらわすことに使う。

ここの使い方はまた別途メモする(かもしれない)。

AmazonWebServiceのSearchIndex現在の一覧

AmazonWebService(AWS)では商品の検索をかける際に、商品分野としてSearchIndexというものを指定する。この項目は20弱程度しかないのだが、Amazon側で分野が追加されると、当然のごとくこちらも追加される。よって書籍やウェブ上の情報が古い場合は、最新のSearchIndexが記載されていないことも多々ある。普段参考にしている「超極めるPHP」という書籍も例外ではない(右下参照)。

ちなみに2007年4月15日現在は以下のものが有効の模様(■が比較的最近追加のもの)。
□Blended:(Amazon全体)
□Books:(本)
□Classical:(クラシック音楽)
□DVD:(DVD)
□Electronics:(電化製品)
□ForeignBooks:(洋書)
■HealthPersonalCare:(ヘルス&ビューティー)
□Hobbies:(ホビー)
□Kitchen:(ホーム&キッチン)
□Music:(音楽)
□MusicTracks:(音楽:曲名から)
□Software:(ソフトウェア)
□SportingGoods:(スポーツ用品)
□Toys:(おもちゃ&ホビー)
□VHS:(ビデオ)
□Video:(DVD&ビデオ)
□VideoGames:(ゲーム)
■Watches:(時計)

URLの正規表現

2007/04/14 | PHPで正規表現

URLを正規表現で記述する方法のメモ(どこかのウェブで以前見つけたものだけど、出典がどこかわからない)。でも、たしか、これだと不十分。しっかり、みっちりRFCにのっとって書くと、この10倍くらいの量になったはず。

$pattern='(https?|ftp)(:¥/¥/[-_.!~*¥'()a-zA-Z0-9;¥/?:¥@&=+¥$,%#]+)';

上記正規表現の出展元にお気づきの方、いらっしゃいましたらご一報ください。
リンク張らせていただきたいので。


守谷市(まちの情報ポータル) 無料アンケートレンタルjpForm.net