3.7.3 データを取得する
3.7.3.1 find
The original text for this section has changed since it was translated. Please help resolve this difference. You can:
find($type, $params)
$type は 'all'、'first'、'count'、'list'、'neighbors' または 'threaded' のいずれかです。デフォルトは 'first' です。
$params はオプションの配列です。キーとして次のものが有効です。:
array(
'conditions' => array('Model.field' => $thisValue), //array of conditions
'recursive' => 1, //int
'fields' => array('Model.field1', 'Model.field2'), //array of field names
'order' => array('Model.created', 'Model.field3 DESC'), //string or array defining order
'group' => array('Model.field'), //fields to GROUP BY
'limit' => n, //int
'page' => n, //int
'callbacks' => true //other possible values are false, 'before', 'after'
) array('conditions' => array('Model.field' => $thisValue), //array of conditions'recursive' => 1, //int'fields' => array('Model.field1', 'Model.field2'), //array of field names'order' => array('Model.created', 'Model.field3 DESC'), //string or array defining order'group' => array('Model.field'), //fields to GROUP BY'limit' => n, //int'page' => n, //int'callbacks' => true //other possible values are false, 'before', 'after')
有効なモデルのコールバックに関する詳細は、こちら を参照してください。
find('list') を使用している場合、$params 内の 'fields' キーは、キー・値・グループを定義します。
// generated list will be indexed by Post.id, with value of Post.title
$this->Post->find('list', array('fields'=>'Post.title'));
// generated list will be indexed by Post.slug, with value of Post.title
$this->Post->find('list', array('fields'=>array('Post.slug', 'Post.title')));
// generated list will be grouped by Post.author_id, and each group indexed (aka, optgroup) by Post.id, with value of Post.title
$this->Post->find('list', array('fields'=>array('Post.id', 'Post.title', 'Post.author_id')));
// generated list will be indexed by Post.id, with value of Post.title$this->Post->find('list', array('fields'=>'Post.title'));// generated list will be indexed by Post.slug, with value of Post.title$this->Post->find('list', array('fields'=>array('Post.slug', 'Post.title')));// generated list will be grouped by Post.author_id, and each group indexed (aka, optgroup) by Post.id, with value of Post.title$this->Post->find('list', array('fields'=>array('Post.id', 'Post.title', 'Post.author_id')));
親テーブルから optgroup ラベルを使いたい場合は、パラメータ中に 'recursive'=>1 をセットすることを忘れないでください。
find('neighbors') を使用する場合は、$params 中の 'field' キーに解析するフィールドを定義し、$params 配列中の 'value' キーには前と後を決定するための値を定義します。'field' と 'value' キーは find('all') では使用しないことに注意してください。 これらは、find('neighbors') だけで特別に使用します。
// assuming we have id's from 1-10, we'll see prev set to 1 and next set to 3
$this->Post->id = 2;
$one = $this->Post->find('neighbors');
// To get the neighboring data using a different field..
$two = $this->Post->find('neighbors', array('field'=>'Post.title', 'value'=>$data['Post']['title']));
// Note that if using 'fields' key for find it must contain your 'field' otherwise it will fail
$three = $this->Post->find('neighbors', array('field'=>'Post.title', 'value'=>$data['Post']['title'], 'fields'=>array('id', 'title'));
// assuming we have id's from 1-10, we'll see prev set to 1 and next set to 3$this->Post->id = 2;$one = $this->Post->find('neighbors');// To get the neighboring data using a different field..$two = $this->Post->find('neighbors', array('field'=>'Post.title', 'value'=>$data['Post']['title']));// Note that if using 'fields' key for find it must contain your 'field' otherwise it will fail$three = $this->Post->find('neighbors', array('field'=>'Post.title', 'value'=>$data['Post']['title'], 'fields'=>array('id', 'title'));
後方互換性のため、 find は古い書式も受け付けます:
find(string $conditions, array $fields, string $order, int $recursive)
MySQL における DISTINCT、 MAX、 MIN 等といった SQL 演算子を使用したい場合は、'fields' キーに次のように指定します。:
$this->Product->find('all', array('fields'=>'DISTINCT (Product.name) AS product_name'));
$this->Product->find('all', array('fields'=>'DISTINCT (Product.name) AS product_name'));
いくつかのフィールドを組み合わせた DISTINCT を使った find を行う場合、つまり、次のような SQL を生成する場合を考えてみましょう。
SELECT DISTINCT Client, Job, Description FROM JOB WHERE Active=1 GROUP BY Client, Job, Description ORDER BY Client
SELECT DISTINCT Client, Job, DescriptionFROM JOBWHERE Active=1GROUP BY Client, Job, DescriptionORDER BY Client
次のようにします。
$condition = array(
'conditions' => array('Model.Active =' => 1),
'fields' => array('DISTINCT Model.Client', 'Model.Job', 'Model.Description'),
'order' => array('Model.Client'),
'group' => array('Model.Client', 'Model.Job', 'Model.Description'));
$this->Model->find('all', $condition);
$condition = array('conditions' => array('Model.Active =' => 1),'fields' => array('DISTINCT Model.Client', 'Model.Job', 'Model.Description'),'order' => array('Model.Client'),'group' => array('Model.Client', 'Model.Job', 'Model.Description'));$this->Model->find('all', $condition);
3.7.3.1.1 find('first')
find('first', $params)
'first' は find のデフォルトの型で、1件の結果を返します。1件だけ結果が欲しい時は、これを使ってください。コントローラ中で使う場合の簡単な例を、いくつか次に示します。
function some_function() {
...
$this->Article->order = null; // これがセットされているとリセットされます
$semiRandomArticle = $this->Article->find();
$this->Article->order = 'Article.created DESC'; // モデルがデフォルトの並び順を持つようにシミュレートします
$lastCreated = $this->Article->find();
$alsoLastCreated = $this->Article->find('first', array('order' => array('Article.created DESC')));
$specificallyThisOne = $this->Article->find('first', array('conditions' => array('Article.id' => 1)));
...
}
function some_function() {...$this->Article->order = null; // これがセットされているとリセットされます$semiRandomArticle = $this->Article->find();$this->Article->order = 'Article.created DESC'; // モデルがデフォルトの並び順を持つようにシミュレートします$lastCreated = $this->Article->find();$alsoLastCreated = $this->Article->find('first', array('order' => array('Article.created DESC')));$specificallyThisOne = $this->Article->find('first', array('conditions' => array('Article.id' => 1)));...}
最初の例では、find にパラメータが一切渡されていません。したがって、検索条件と並び順が使用されません。find('first') が返す値は、次のような形式になります。
Array
(
[ModelName] => Array
(
[id] => 83
[field1] => value1
[field2] => value2
[field3] => value3
)
[AssociatedModelName] => Array
(
[id] => 1
[field1] => value1
[field2] => value2
[field3] => value3
)
)
find('first') において使用する追加のパラメータは、前述したもので全てです。
3.7.3.1.2 find('count')
find('count', $params)
find('count', $params) は整数型の値を返します。コントローラ中で使う場合の簡単な例を、いくつか次に示します。
function some_function() {
...
$total = $this->Article->find('count');
$pending = $this->Article->find('count', array('conditions' => array('Article.status' => 'pending')));
$authors = $this->Article->User->find('count');
$publishedAuthors = $this->Article->find('count', array(
'fields' => 'DISTINCT Article.user_id',
'conditions' => array('Article.status !=' => 'pending')
));
...
}
function some_function() {...$total = $this->Article->find('count');$pending = $this->Article->find('count', array('conditions' => array('Article.status' => 'pending')));$authors = $this->Article->User->find('count');$publishedAuthors = $this->Article->find('count', array('fields' => 'DISTINCT Article.user_id','conditions' => array('Article.status !=' => 'pending')));...}
find('count') では、 fields に配列を渡してはいけません。DISTINCT カウントを行うフィールドだけを指定するようにしてください。そうすることで、条件に従った結果が常に同じになります。
find('count') において使用する追加のパラメータは、前述したもので全てです。
3.7.3.1.3 find('all')
このセクションには保留されている変更があります. More information about translations
find('all', $params)
find('all') returns an array of (potentially multiple) results. It is in fact the mechanism used by all find() variants, as well as paginate. Below are a couple of simple (controller code) examples:
function some_function() {
...
$allArticles = $this->Article->find('all');
$pending = $this->Article->find('all', array('conditions' => array('Article.status' => 'pending')));
$allAuthors = $this->Article->User->find('all');
$allPublishedAuthors = $this->Article->User->find('all', array('conditions' => array('Article.status !=' => 'pending')));
...
}
function some_function() {...$allArticles = $this->Article->find('all');$pending = $this->Article->find('all', array('conditions' => array('Article.status' => 'pending')));$allAuthors = $this->Article->User->find('all');$allPublishedAuthors = $this->Article->User->find('all', array('conditions' => array('Article.status !=' => 'pending')));...}
In the above example $allAuthors will contain every user in the users table, there will be no condition applied to the find as none were passed.
The results of a call to find('all') will be of the following form:
Array
(
[0] => Array
(
[ModelName] => Array
(
[id] => 83
[field1] => value1
[field2] => value2
[field3] => value3
)
[AssociatedModelName] => Array
(
[id] => 1
[field1] => value1
[field2] => value2
[field3] => value3
)
)
)
There are no additional parameters used by find('all').
3.7.3.1.4 find('list')
このセクションには保留されている変更があります. More information about translations
find('list', $params)
find('list', $params) returns an indexed array, useful for any use where you would want a list such as for populating input select boxes. Below are a couple of simple (controller code) examples:
function some_function() {
...
$allArticles = $this->Article->find('list');
$pending = $this->Article->find('list', array('conditions' => array('Article.status' => 'pending')));
$allAuthors = $this->Article->User->find('list');
$allPublishedAuthors = $this->Article->User->find('list', array('conditions' => array('Article.status !=' => 'pending')));
...
}
function some_function() {...$allArticles = $this->Article->find('list');$pending = $this->Article->find('list', array('conditions' => array('Article.status' => 'pending')));$allAuthors = $this->Article->User->find('list');$allPublishedAuthors = $this->Article->User->find('list', array('conditions' => array('Article.status !=' => 'pending')));...}
In the above example $allAuthors will contain every user in the users table, there will be no condition applied to the find as none were passed.
The results of a call to find('list') will be in the following form:
Array
(
//[id] => 'displayValue',
[1] => 'displayValue1',
[2] => 'displayValue2',
[4] => 'displayValue4',
[5] => 'displayValue5',
[6] => 'displayValue6',
[3] => 'displayValue3',
)
When calling find('list') the fields passed are used to determine what should be used as the array key, value and optionally what to group the results by. By default the primary key for the model is used for the key, and the display field (which can be configured using the model attribute displayField) is used for the value. Some further examples to clarify:.
function some_function() {
...
$justusernames = $this->Article->User->find('list', array('fields' => array('User.username')));
$usernameMap = $this->Article->User->find('list', array('fields' => array('User.username', 'User.first_name')));
$usernameGroups = $this->Article->User->find('list', array('fields' => array('User.username', 'User.first_name', 'User.group')));
...
}
function some_function() {...$justusernames = $this->Article->User->find('list', array('fields' => array('User.username')));$usernameMap = $this->Article->User->find('list', array('fields' => array('User.username', 'User.first_name')));$usernameGroups = $this->Article->User->find('list', array('fields' => array('User.username', 'User.first_name', 'User.group')));...}
With the above code example, the resultant vars would look something like this:
$justusernames = Array
(
//[id] => 'username',
[213] => 'AD7six',
[25] => '_psychic_',
[1] => 'PHPNut',
[2] => 'gwoo',
[400] => 'jperras',
)
$usernameMap = Array
(
//[username] => 'firstname',
['AD7six'] => 'Andy',
['_psychic_'] => 'John',
['PHPNut'] => 'Larry',
['gwoo'] => 'Gwoo',
['jperras'] => 'Joël',
)
$usernameGroups = Array
(
['Uber'] => Array
(
['PHPNut'] => 'Larry',
['gwoo'] => 'Gwoo',
)
['Admin'] => Array
(
['_psychic_'] => 'John',
['AD7six'] => 'Andy',
['jperras'] => 'Joël',
)
)
3.7.3.1.5 find('threaded')
このセクションには保留されている変更があります. More information about translations
find('threaded', $params)
find('threaded', $params) returns a nested array, and is appropriate if you want to use the parent_id field of your model data to build nested results. Below are a couple of simple (controller code) examples:
function some_function() {
...
$allCategories = $this->Category->find('threaded');
$aCategory = $this->Category->find('first', array('conditions' => array('parent_id' => 42))); // not the root
$someCategories = $this->Category->find('threaded', array(
'conditions' => array(
'Article.lft >=' => $aCategory['Category']['lft'],
'Article.rght <=' => $aCategory['Category']['rght']
)
));
...
}
function some_function() {...$allCategories = $this->Category->find('threaded');$aCategory = $this->Category->find('first', array('conditions' => array('parent_id' => 42))); // not the root$someCategories = $this->Category->find('threaded', array('conditions' => array('Article.lft >=' => $aCategory['Category']['lft'],'Article.rght <=' => $aCategory['Category']['rght'])));...}
It is not necessary to use the Tree behavior to use this method - but all desired results must be possible to be found in a single query.
In the above code example, $allCategories will contain a nested array representing the whole category structure. The second example makes use of the data structure used by the Tree behavior the return a partial, nested, result for $aCategory and everything below it. The results of a call to find('threaded') will be of the following form:
Array
(
[0] => Array
(
[ModelName] => Array
(
[id] => 83
[parent_id] => null
[field1] => value1
[field2] => value2
[field3] => value3
)
[AssociatedModelName] => Array
(
[id] => 1
[field1] => value1
[field2] => value2
[field3] => value3
)
[children] => Array
(
[0] => Array
(
[ModelName] => Array
(
[id] => 42
[parent_id] => 83
[field1] => value1
[field2] => value2
[field3] => value3
)
[AssociatedModelName] => Array
(
[id] => 2
[field1] => value1
[field2] => value2
[field3] => value3
)
[children] => Array
(
)
)
...
)
)
)
The order results appear can be changed as it is influence by the order of processing. For example, if 'order' => 'name ASC' is passed in the params to find('threaded'), the results will appear in name order. Likewise any order can be used, there is no inbuilt requirement of this method for the top result to be returned first.
There are no additional parameters used by find('threaded').
3.7.3.1.6 find('neighbors')
このセクションには保留されている変更があります. More information about translations
find('neighbors', $params)
'neighbors' will perform a find similar to 'first', but will return the row before and after the one you request. Below is a simple (controller code) example:
function some_function() {
$neighbors = $this->Article->find('neighbors', array('fields' => 'id', 'value' => 3));
}
function some_function() {$neighbors = $this->Article->find('neighbors', array('fields' => 'id', 'value' => 3));}
You can see in this example the two required elements of the $params array: field and value. Other elements are still allowed as with any other find (Ex: If your model acts as containable, then you can specify 'contain' in $params). The format returned from a find('neighbors') call is in the form:
Array
(
[prev] => Array
(
[ModelName] => Array
(
[id] => 2
[field1] => value1
[field2] => value2
...
)
[AssociatedModelName] => Array
(
[id] => 151
[field1] => value1
[field2] => value2
...
)
)
[next] => Array
(
[ModelName] => Array
(
[id] => 4
[field1] => value1
[field2] => value2
...
)
[AssociatedModelName] => Array
(
[id] => 122
[field1] => value1
[field2] => value2
...
)
)
)
Note how the result always contains only two root elements: prev and next.
3.7.3.2 findAllBy
The original text for this section has changed since it was translated. Please help resolve this difference. You can:
findAllBy
これらの魔法のような関数はあるフィールドを指定してテーブルを検索するためのショートカットとして使用することができます。関数名の最後にキャメルケース形式のフィールド名を追加し、第1引数としてそのフィールド用の判定基準を与えてください。
3.7.3.3 findBy
The original text for this section has changed since it was translated. Please help resolve this difference. You can:
findBy
これらの魔法のような関数はあるフィールドを指定してテーブルを検索するためのショートカットとして使用することができます。関数名の最後にキャメルケース形式のフィールド名を追加し、第1引数としてそのフィールド用の判定基準を与えてください。
| PHP5 findAllBy |
対応する SQL |
|---|---|
| $this->Product->findAllByOrderStatus(‘3’); | Product.order_status = 3 |
| $this->Recipe->findAllByType(‘Cookie’); | Recipe.type = ‘Cookie’ |
| $this->User->findAllByLastName(‘Anderson’); | User.last_name = ‘Anderson’ |
| $this->Cake->findById(7); | Cake.id = 7 |
| $this->User->findByUserName(‘psychic’); | User.user_name = ‘psychic’ |
PHP4 は、大文字と小文字を区別しないため、この関数の使用方法は少々異なります:
| PHP4 findAllBy |
対応する SQL |
|---|---|
| $this->Product->findAllByOrder_status(‘3’); | Product.order_status = 3 |
| $this->Recipe->findAllByType(‘Cookie’); | Recipe.type = ‘Cookie’ |
| $this->User->findAllByLast_name(‘Anderson’); | User.last_name = ‘Anderson’ |
| $this->Cake->findById(7); | Cake.id = 7 |
| $this->User->findByUser_name(‘psychic’); | User.user_name = ‘psychic’ |
findBy() 関数は find('first',...) と、 findAllBy() 関数は find('all',...) と似ています。
いずれの場合でも、返り値は配列となり、 find() または findAll() を実行したときと同じ形式になります。
3.7.3.4 query
The original text for this section has changed since it was translated. Please help resolve this difference. You can:
query(string $query)
モデルの query() メソッドを使用すると独自の SQL 呼び出しを作成できます。
アプリケーションで独自の SQL クエリーを使用している場合、CakePHP の Sanitize ライブラリ(このマニュアルの後で説明されています)を必ず参照してください。SQL インジェクションやクロスサイトスクリプティング攻撃を防ぐためにユーザデータをきれいにする目的があります。
query() は、モデルの呼び出しとは本質的に分離した機能で、 $Model->cachequeries の状態に従いません。query を呼び出すにあたりキャッシングを無効にするには、query($query, $cachequeries = false) というように第2引数に false を設定します。
query() のクエリ文中ではモデル名でなく、テーブル名を使用し、返却される配列のキーもテーブル名になります。例えば、
$this->Picture->query("SELECT * FROM pictures LIMIT 2;");
$this->Picture->query("SELECT * FROM pictures LIMIT 2;");
これの戻り値は以下の通りです。
Array
(
[0] => Array
(
[pictures] => Array
(
[id] => 1304
[user_id] => 759
)
)
[1] => Array
(
[pictures] => Array
(
[id] => 1305
[user_id] => 759
)
)
)
Array([0] => Array([pictures] => Array([id] => 1304[user_id] => 759))[1] => Array([pictures] => Array([id] => 1305[user_id] => 759)))
配列のキー値にモデル名を使用し、Findメソッドを使用した時との一貫性を持たせる場合は、クエリは以下のようにします:
$this->Picture->query("SELECT * FROM pictures AS Picture LIMIT 2;");
$this->Picture->query("SELECT * FROM pictures AS Picture LIMIT 2;");
戻り値は次のようになります。
Array
(
[0] => Array
(
[Picture] => Array
(
[id] => 1304
[user_id] => 759
)
)
[1] => Array
(
[Picture] => Array
(
[id] => 1305
[user_id] => 759
)
)
)
Array([0] => Array([Picture] => Array([id] => 1304[user_id] => 759))[1] => Array([Picture] => Array([id] => 1305[user_id] => 759)))
3.7.3.5 field
field(string $name, array $conditions = null, string $order = null)
$order の順に $conditions にマッチした最初のレコードから $name で指定した単一のフィールドの値を返します。 conditions が渡されておらず、モデルの id がセットされていた場合、現在のモデルの結果がフィールドの値として返されます。マッチしたレコードが見つからなかった場合、 false が返されます。
$model->id = 22;
echo $model->field('name'); // id が 22 の name が出力されます
echo $model->field('name', array('created <' => date('Y-m-d H:i:s')), 'created DESC'); // 最後に作成されたインスタンスの name が出力されます
$model->id = 22;echo $model->field('name'); // id が 22 の name が出力されますecho $model->field('name', array('created <' => date('Y-m-d H:i:s')), 'created DESC'); // 最後に作成されたインスタンスの name が出力されます
3.7.3.6 read()
このセクションには保留されている変更があります. More information about translations
read($fields, $id)
read() is a method used to set the current model data (Model::$data)--such as during edits--but it can also be used in other circumstances to retrieve a single record from the database.
$fields is used to pass a single field name, as a string, or an array of field names; if left empty, all fields will be fetched.
$id specifies the ID of the record to be read. By default, the currently selected record, as specified by Model::$id, is used. Passing a different value to $id will cause that record to be selected.
read() always returns an array (even if only a single field
name is requested). Use field to retrieve the value of a single
field.
function beforeDelete($cascade) {
...
$rating = $this->read('rating'); // gets the rating of the record being deleted.
$name = $this->read('name', $id2); // gets the name of a second record.
$rating = $this->read('rating'); // gets the rating of the second record.
$this->id = $id3; //
$this->Article->read(); // reads a third record
$record = $this->data // stores the third record in $record
...
}
function beforeDelete($cascade) {...$rating = $this->read('rating'); // gets the rating of the record being deleted.$name = $this->read('name', $id2); // gets the name of a second record.$rating = $this->read('rating'); // gets the rating of the second record.$this->id = $id3; //$this->Article->read(); // reads a third record$record = $this->data // stores the third record in $record...}
Notice that the third call to read() fetches the rating of the same record read before. That is because read() changes Model::$id to any value passed as $id. Lines 6-8 demonstrate how read() changes the current model data.
3.7.3.7 複雑な find の条件
The original text for this section has changed since it was translated. Please help resolve this difference. You can:
多くの場合モデルの find 呼び出しをする際に、様々な方法で検索条件のセットを渡すことになります。最も簡単な方法は、SQL の WHERE 句の抜粋を使用することです。もっと細かく制御する必要がある場合、配列を使用します。
配列を使用すると、すっきりと読みやすくなり、クエリーを作成しやすくなります。この構文はクエリーの要素(fields, values, operators など)を分離し、扱いやすくします。このおかげで CakePHP は最も効率よくクエリーを生成することが可能になり、適切な SQL 構文を保証し、クエリーの各部分を適切にエスケープすることができます。
ごく基本的な配列をベースにしたクエリは、次のようになります。:
$conditions = array("Post.title" => "This is a post");
//モデルでの使用例:
$this->Post->find($conditions);
$conditions = array("Post.title" => "This is a post");//モデルでの使用例:$this->Post->find($conditions);
この構造はどういうことを表すか一目瞭然です: title が "This is a post" と等しいすべての Post を検索します。フィールド名として "title" だけを使用することができますが、クエリーを構築する際に常にモデル名を指定する習慣をつけておきましょう。コードが明確になりますし、後にスキーマを変更した際の衝突を避けるのに役立ちます。
他の形式の条件についてはどうでしょうか?これも同じように簡単です。title が "This is a post" ではない Post をすべて検索してみましょう:
array("Post.title <>" => "This is a post")
array("Post.title <>" => "This is a post")
フィールド名の次に続く '<>' に注意してください。CakePHP はあらゆる有効な SQL 比較演算子を解析することができます。たとえば、LIKE, BETWEEN, REGEX のような一致表現を含みます。ただし、フィールド名と演算子の間にはスペースが必要です。一つの例外は IN (...) 形式の条件です。さて、title が与えられた値に含まれる Post を検索してみましょう:
array(
"Post.title" => array("First post", "Second post", "Third post")
)
array("Post.title" => array("First post", "Second post", "Third post"))
与えた値以外の title で、NOT IN(...) によるマッチにより posts を検索する場合は次のようにします:
array(
"NOT" => array( "Post.title" => array("First post", "Second post", "Third post") )
)
array("NOT" => array( "Post.title" => array("First post", "Second post", "Third post") ))
条件にフィルタを追加するには、キー/値を配列に追加するだけです:
array (
"Post.title" => array("First post", "Second post", "Third post"),
"Post.created >" => date('Y-m-d', strtotime("-2 weeks"))
)
array ("Post.title" => array("First post", "Second post", "Third post"),"Post.created >" => date('Y-m-d', strtotime("-2 weeks")))
データベース内の2つのフィールドを比較する検索を作成することもできます。
array("Post.created = Post.modified")
array("Post.created = Post.modified")
上記の例は、作成日付(created date)と更新日付(modified date)が等しい複数の Post を返します。(1度も更新されていない Post も返します)
このメソッドの中に WHERE 句として定義することができないものがあった場合(例えばブール値の操作)、文字列のようにして定義できることをおぼえておいてください:
array(
'Model.field & 8 = 1',
//other conditions as usual
)
array('Model.field & 8 = 1',//other conditions as usual)
デフォルトでは、CakePHP は複数の条件を AND で結合します。これは次のことを意味します。抜粋した上記コードは、2週間前に生成され、かつ title が与えられた値にマッチする Post だけを取得します。しかし、簡単にどちらかの条件にマッチする Post を検索することもできます。:
array( "or" => array (
"Post.title" => array("First post", "Second post", "Third post"),
"Post.created >" => date('Y-m-d', strtotime("-2 weeks"))
)
)
array( "or" => array ("Post.title" => array("First post", "Second post", "Third post"),"Post.created >" => date('Y-m-d', strtotime("-2 weeks"))))
CCake はすべての有効な SQL 演算子(AND, OR, NOT, XOR など)を使用できます。大文字でも小文字でもどちらでも構いません。これらの条件は無制限にネストすることができます。Posts と Authors に belongsTo の関連があるとします。あるキーワード (“magic”) を含むか、または2週間前に作成されたすべての Post のうち、 Bob によって記述された Post のみ取得してみましょう:
array (
"Author.name" => "Bob",
"or" => array (
"Post.title LIKE" => "%magic%",
"Post.created >" => date('Y-m-d', strtotime("-2 weeks"))
)
)
array ("Author.name" => "Bob","or" => array ("Post.title LIKE" => "%magic%","Post.created >" => date('Y-m-d', strtotime("-2 weeks"))))
Cake は値が null のフィールドをチェックすることもできます。この例では、クエリーは Post の title が null ではないレコードを返します:
array ("not" => array (
"Post.title" => null,
)
)
array ("not" => array ("Post.title" => null,))
BETWEEN クエリーを処理するには、次のように使用することができます:
array('Post.id BETWEEN ?AND ?' => array(1,10)) array('Post.id BETWEEN ?AND ?' => array(1,10))
注意: CakePHP は使用している DB のフィールドの型に依存して数値をクォートします。
GROUP BY はどのように行うのでしょうか?
array('fields'=>array('Product.type','MIN(Product.price) as price'), 'group' => 'Product.type');
array('fields'=>array('Product.type','MIN(Product.price) as price'), 'group' => 'Product.type');
DISTINCT クエリを用いた簡単な例は次のようになります。MIN() や MAX()、その他の演算子も、同じように扱えます。
array('fields'=>array('DISTINCT (User.name) AS my_column_name'), 'order'=>array('User.id DESC'));
array('fields'=>array('DISTINCT (User.name) AS my_column_name'), 'order'=>array('User.id DESC'));
とても複雑な条件を、ネストした複数の条件の配列によって作成することができます:
array(
'OR' => array(
array('Company.name' => 'Future Holdings'),
array('Company.name' => 'Steel Mega Works')
),
'AND' => array(
array(
'OR'=>array(
array('Company.status' => 'active'),
'NOT'=>array(
array('Company.status'=> array('inactive', 'suspended'))
)
)
)
)
);
array('OR' => array(array('Company.name' => 'Future Holdings'),array('Company.name' => 'Steel Mega Works')),'AND' => array(array('OR'=>array(array('Company.status' => 'active'),'NOT'=>array(array('Company.status'=> array('inactive', 'suspended')))))));
これは次のような SQL になります:
SELECT `Company`.`id`, `Company`.`name`,
`Company`.`description`, `Company`.`location`,
`Company`.`created`, `Company`.`status`, `Company`.`size`
FROM
`companies` AS `Company`
WHERE
((`Company`.`name` = 'Future Holdings')
OR
(`Company`.`name` = 'Steel Mega Works'))
AND
((`Company`.`status` = 'active')
OR (NOT (`Company`.`status` IN ('inactive', 'suspended'))))
SELECT `Company`.`id`, `Company`.`name`,`Company`.`description`, `Company`.`location`,`Company`.`created`, `Company`.`status`, `Company`.`size`FROM`companies` AS `Company`WHERE((`Company`.`name` = 'Future Holdings')OR(`Company`.`name` = 'Steel Mega Works'))AND((`Company`.`status` = 'active')OR (NOT (`Company`.`status` IN ('inactive', 'suspended'))))
