cakephp3でモデル(find+xxxx)任意のfindメソッドを準備する
モデルでデータを取得する場合はfindメソッドを使用することが多いと思う
<?php namespace App\Shell; use Cake\Console\Shell; use Cake\ORM\TableRegistry; /** * Sample1 shell command. */ class Sample1Shell extends Shell { /** * main() method. * * @return bool|int Success or error code. */ public function main() { // table $bookmarks = TableRegistry::get('bookmarks'); // find $query = $bookmarks ->find() ->contain(['users']); // SQ print_r($query->sql()); print_r("\n"); } }
※findメソッドにいろいろな条件を付与して様々な結果を取得するけど
ある程度まとめたい
毎回findに条件を付与するより、可変パラメータだけを渡したいな〜
find+任意の名前でメソッドを作成
サンプル
<?php namespace App\Model\Table; use App\Model\Entity\Bookmark; use Cake\ORM\Query; use Cake\ORM\RulesChecker; use Cake\ORM\Table; use Cake\Validation\Validator; /** * Bookmarks Model */ class BookmarksTable extends Table { /** * Initialize method * * @param array $config The configuration for the Table. * @return void */ public function initialize(array $config) { $this->table('bookmarks'); $this->displayField('title'); $this->primaryKey('id'); $this->addBehavior('Timestamp'); $this->belongsTo('Users', [ 'foreignKey' => 'user_id' ]); $this->belongsToMany('Tags', [ 'foreignKey' => 'bookmark_id', 'targetForeignKey' => 'tag_id', 'joinTable' => 'bookmarks_tags' ]); } /** * Default validation rules. * * @param \Cake\Validation\Validator $validator Validator instance. * @return \Cake\Validation\Validator */ public function validationDefault(Validator $validator) { $validator ->add('id', 'valid', ['rule' => 'numeric']) ->allowEmpty('id', 'create') ->add('user_id', 'valid', ['rule' => 'numeric']) ->requirePresence('user_id', 'create') ->notEmpty('user_id') ->allowEmpty('title') ->allowEmpty('description') ->allowEmpty('url'); return $validator; } /** * Returns a rules checker object that will be used for validating * application integrity. * * @param \Cake\ORM\RulesChecker $rules The rules object to be modified. * @return \Cake\ORM\RulesChecker */ public function buildRules(RulesChecker $rules) { $rules->add($rules->existsIn(['user_id'], 'Users')); return $rules; } // これです public function findTagged(Query $query, array $options){ return $this ->find() ->matching('Tags', function ($q) use ($options) { return $q->where(['Tags.title IN' => $options['tags']]); }); } }
※Tableのクラスに追加
それで、Tableのクラスを使用するところでfind以降のメソッド名を指定
<?php namespace App\Shell; use Cake\Console\Shell; use Cake\ORM\TableRegistry; /** * Sample2 shell command. */ class Sample2Shell extends Shell { /** * main() method. * * @return bool|int Success or error code. */ public function main() { // table $bookmarks = TableRegistry::get('bookmarks'); // find $query = $bookmarks->find('tagged', [ 'tags' => ['111', '222'] ]); // SQ print_r($query->sql()); print_r("\n"); } }
※第1引数のパラメータで"find"以降のメソッド名を指定する
こうすることで取得できる
戻り値はまあ好きに対応することが可能と思います
結果
SELECT bookmarks.id AS `bookmarks__id` , bookmarks.user_id AS `bookmarks__user_id` , bookmarks.title AS `bookmarks__title` , bookmarks.description AS `bookmarks__description` , bookmarks.url AS `bookmarks__url` , bookmarks.created AS `bookmarks__created` , bookmarks.updated AS `bookmarks__updated` , Tags.id AS `Tags__id` , Tags.title AS `Tags__title` , Tags.created AS `Tags__created` , Tags.updated AS `Tags__updated` , BookmarksTags.bookmark_id AS `BookmarksTags__bookmark_id` , BookmarksTags.tag_id AS `BookmarksTags__tag_id` FROM bookmarks bookmarks INNER JOIN tags Tags ON Tags.title in (:c0,:c1) INNER JOIN bookmarks_tags BookmarksTags ON ( bookmarks.id = (BookmarksTags.bookmark_id) AND Tags.id = (BookmarksTags.tag_id) )
所感
チュートリアルをやっていきながら不明な場所を解決して理解を進めていくようにします