1

私は CakePHP を使い始めたばかりで、いくつかの問題にぶつかりました。次のようなmysqlデータベース(ArtistとArtistSurname)の2つのテーブルを検索するためのこの検索機能があります。

class ArtistsController extends AppController {
public function search ($search) {
    if ($search){
    $artists = $this->Artist->find('all', array('conditions' => array("surname like '%$search%' AND Artist.id = ArtistSurname.artist_id OR firstname like '%$search%' AND Artist.id = ArtistSurname.artist_id"), 'limit' => 400, 'fields' => array('Artist.firstname', 'ArtistSurname.surname', 'Artist.dbirth', 'Artist.id')));
    if (!$artists){
        throw new NotFoundException(__('No search result.'));
    }
    $result = array();
    foreach ($artists as $artist) {
    $fetchedArtist = array('value' => $artist['ArtistSurname']['surname'] . " " . $artist['Artist']['firstname'], 'year' => $artist['Artist']['dbirth'], 'id' => $artist['Artist']['id']);
    array_push($result, $fetchedArtist);
    }
    header("Content-Type: application/json");
    echo json_encode($result);
    $this->autoRender = false;
    }
}

クエリの後、結果をオートコンプリート (typeahead.js) の新しい読み取り可能な配列に入れ、これを json としてエコーします。これは、クエリが姓のみを検索する場合ではなく、クエリが名を検索する限り正常に機能します。奇妙なことは、最初の名前が見つかったときに GET 要求から application/json のみを受け取ることです。それ以外の場合は、text/html で正しい結果が得られます。どうしてこれなの?

4

1 に答える 1

2

姓を格納するために別のテーブルを使用しており、基本的に条件の一部としてINNER JOIN指定して (2 回) を構築しています。Artist.id = ArtistSurname.artist_id

また、条件を間違った方法で定義しています。CakePHP が適切に値をエスケープするように、各条件/フィールドに「配列」表記を使用する必要があります。

$artists = $this->Artist->find('all', array(
    'conditions' => array(
         'OR' => array(   
             'ArtistSurname.surname LIKE' => '%' . $search . '%',
             'Artist.firstname LIKE' =>  '%' . $search . '%',
         )
    ),
    joins => array(
        array(
          'table' => 'artist_surnames',
          'alias' => 'ArtistSurname',
          'type' => 'LEFT',
          'conditions' => array(
              'Artist.id = ArtistSurname.artist_id',
          )
       ),
    ),
    'limit' => 400, 
    'fields' => array(
        'Artist.firstname', 
        'ArtistSurname.surname',
        'Artist.dbirth',
        'Artist.id'
     )
));

「姓」が見つからない場合にも結果が返されるように、ArtistSurname <-> アーティスト関係を「LEFT」結合に変換しました。

通常、クエリでこれらの関係を手動で指定する必要はありませんが、モデルの関係 (ArtistSurname->belongsTo->Artist) で指定します。

http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html#associations-linking-models-together

ただし、元の機能にできるだけ近づけるように努めました。

なぜアーティストの姓に別のモデルを使用しているのですか? これをそれほど複雑にする理由は思いつきませんか?

于 2013-03-29T18:27:51.457 に答える