

### 環境と現状

  * cakephp2.7 （フレームワーク初挑戦です）
  * mysql

  * DBの構造

  * Sites 
    * id
    * site_name
    * site_url
  * Articles 
    * id
    * site_id （Sites の id と連動しています）
    * article_title
    * article_url
    * pub_date （記事が更新された時間です）

* * *

### Contoller

IndexesController.php

[code]

    class IndexesController extends AppController {
    
      public $uses = ['Article'];
    
      public function index() {
        $indexArticles = $this->Article->find('all', array(
          'fieleds' => array('article_title', 'article_url', 'pub_date'),
          'order' => array('pub_date' => 'desc'),
          'limit' => 50
        ));
    
        $this->set('indexArticles', $indexArticles);
    
      }
    }
    
[/code]

### Model

### View

Indexes/index.ctp

[code]

    <table>
      <tr>
        <th>更新時間</th>
        <th>記事タイトル</th>
      </tr>
    <?php
    
    foreach ($indexArticles as $data) {
      $title = $data['Article']['article_title'];
      $link = $data['Article']['article_url'];
      $pub_date = $data['Article']['pub_date'];
    
      echo '<tr>';
      echo '<td>'.$pub_date.'</td>';
      echo '<td><a href="'.$link.'" target="_blank">'.$title.'</a></td>';
      echo '</tr>';
    }
    ?>
    </table>
    
[/code]

* * *

となっており、Articles からの記事情報の取得はできています。

これで index ページに記事の一覧を表示させています。

### 目的

  * hoge.com というアンテナサイトを構築する。
  * hoge.com のトップページは、最新記事の一覧とサイト名が羅列されている。
  * （↓蛇足）
  * hoge.com/Sites/ で登録されているサイト一覧
  * hoge.com/Sites/1 で Sites id 1 のサイトの最新記事一覧が表示される

cakephp のアソシエーションを利用してこのような記事リンクに対してサイト名の表示をしたいのが目的です。

<http://kita-kore.com/> のようなアンテナサイトを想像してもらえるとわかりやすいかと思います。

[![画像の説明をここに入力](https://i.stack.imgur.com/WSOZ6.png)](https://i.stack.imgur.com/WSOZ6.png)

ひと通りcakephp のチュートリアルを勉強した結果、アソシエーションの `$hasMany`
を使うのかなと想像しているのですが、どういう構築をしたらいいのかわかりません。

Controller を IndexesController.php としているのがそもそもナンセンスなのか  
SitesController.php でやりたい処理を書くのか、というのも理解していません。

是非、ご回答よろしくお願いします。


CC BY-SA 3.0
2015-07-31T06:51:39.490
12874
2015-07-31T11:29:33.827
10741
question
php cakephp
cakephp アソシエーションでモデル名、コントローラ名が特殊(?)な場合の設定方法


この場合、モデルの関係は `Site "hasMany" Article`, `Article "belongsTo" Site` となります。

IndexesControllerでは、ArticleにSiteを紐付けて表示したいのでArticleモデルへbelongsToのアソシエーションを設定します。

<http://book.cakephp.org/2.0/ja/models/associations-linking-models-
together.html#belongsto>

[code]

    <?php
    
    class Article extends Model {
        // ... (snip)
        public $belongsTo = [
            'Site' => [
                'className' => 'Site',
                'foreignKey' => 'site_id',
            ],
        ];
        // ... (snip)
    }
    
[/code]

コントローラー側での取得時に `fields` に `Site.site_name`, `Site.site_url`を追加します。

[code]

    $indexArticles = $this->Article->find('all', array(
      'fieleds' => array('Article.article_title', 'Article.article_url', 'Article.pub_date', 'Site.site_name', 'Site.site_url'),
      'order' => array('pub_date' => 'desc'),
      'limit' => 50
    ));
    
[/code]

これで、

[code]

    [
       ['Article' => [ 'article_name' => ... ], 'Site' => [ 'site_name' => ... ]],
       ['Article' => [ ... ], 'Site' => [ ... ]],
    ]
    
[/code]

のような形でデータを取得できます。

### 補足

Viewで値をそのままechoしているので、記事タイトルやURLにHTMLタグがあるとそのまま表示されることになり、XSS脆弱性があるといえます。

リンクの部分は`HtmlHelper::link`を使用するか`h()`関数を通してエスケープしてください。

[code]

    <table>
      <tr>
        <th>更新時間</th>
        <th>記事タイトル</th>
      </tr>
      <?php foreach ($indexArticles as $data) : ?>
      <tr>
        <td><?php echo h($data['Article']['pub_date']); ?></td>
        <td><?php echo $this->Html->link($data['Article']['article_title'], $data['Article']['article_url'], ['target' => '_blank']); ?></td>
      </tr>
      <?php endforeach; ?>
    </table>
    
[/code]


CC BY-SA 3.0
2015-07-31T11:29:33.827
12884
2015-07-31T11:29:33.827
2668
12874
answer