2011-09-04 9 views
3

私は現在作業しているアプリケーションでアクティビティの概要ページを作成しようとしています。私は、次の操作を行う必要があることを確認した:複雑なCakePHPデータのリターンとコンバート

私が加入しています人々からのすべてのストーリーを取得し、次のようにそれらをフォーマット:

[Username] has posted [StoryName] - View story 

は、私が接続されていますユーザーのすべてのストーリーが上のコメントを掲載しているために取得します

[Username] has posted a comment on [StoryName] - View story 

私は、両方の配列を取得し、それらを私はしたい形式を表示しますが(Facebookのような人が行うのと同じ方法で)投稿日によってそれらを注文することができますかわからないよ

これを進めるにはどうすればよいでしょうか?

注:回答は簡単に拡張可能なものでなければなりません。私は、WordPressのモデルに従うことを検討しており、投稿タイプフィールドを持つ投稿テーブルを作成しています。

答えて

4

あなたがやろうとしているのは、CakePHPを組み込んだものです。大きなことは、モデルが適切に関連付けられていることを確認することです。これが達成されると、ケーキはあなたのために大々的に持ち上げます。あなたの状況については

、このように関連する3つのモデルを使用:ケーキの規則に基づいて、あなたのテーブルを設定

class Story extends AppModel{ 
    var $belongsTo = 'Author'; 
    var $hasMany = 'Comment'; 
} 

class Author extends AppModel{ 
    var $hasMany = array('Story', 'Comment'); 
    var $hasAndBelongsToMany = 'User'; 
} 

class Comment extends AppModel{ 
    var $belongsTo = array('Author', 'Story'); 
} 

を。次に、あなたのコントローラにはほとんどCakePHPの魔法:何が起こっているの

$this->Story->Author->bindModel(array('hasOne' => array('AuthorsUsers'))); 
$myAuthors = $this->Story->Author->find('list', array(
    'fields' => array('id'), 
    'conditions' => array('AuthorsUsers.user_id' => $userId), 
    'recursive' => false 
    )); 

$stories = $this->Story->find('all', array(
    'fields' => array('Story.id', 'Story.title', 'Author.id', 'Author.name'), 
    'order' => 'published_date DESC', 
    'conditions' => array('Author.id' => $myAuthors), 
    'recursive' => 2 
    )); 

クイック説明:

  • bindModel()はケーキができますが、あなたが関連付けられているユーザIDで著者を見つけるために、HABTMの関連付けを使用することを知っています。 (ケーキの規約では、 'authors_users'というテーブルを作成者 - >ユーザHABTMの関連付けに参加させることです)
  • $myAuthors変数をデバッグすると、IDの単純な配列が得られます。
  • 'conditions' => array('field' => array())は「WHEREフィールドIN(...)」として解析されます。この例では、すべてのモデルを取得しますWHERE 'Author.id' IN $myAuthors
  • 短い$this->Story->find()コールはケーキの美しさです。指定された条件に一致するすべてのStoryモデルを自動的に検索します。は、発見された各ストーリーに関連する他のモデルを検出します。 (あなたはRecursiveをオフにするかContainable行動を使用して、関連するモデルを見つけることがないことを伝えることができます。)
  • $stories変数は次のようにあなたの構造が表示されますデバッグ:
Array 
(
    [0] => Array 
     (
      [Story] => Array 
       (
        [id] => 1 
        [title] => 'Common Sense' 
        [published_date] => 1776-01-10 
       ) 
      [Author] => Array 
       (
        [id] => 1 
        [name] => 'Thomas Paine' 
       ) 
      [Comment] => Array 
       (
        [0] => Array 
         (
          [id] => 1 
          [text] => 'Revolutionary!' 
          [Author] => Array 
           (
            [id] => 3 
            [name] => 'Silence Dogood' 
           ) 
         ) 
        [1...n] => ... 
       ) 
     ) 
    [1...n] => ... 
) 

あなたが、その後することができますビュー内のその構造を使用して、必要に応じてデータを表示します。

ただ1つのクエリでそれを行う方法があるはずですが、この方法では動作し、サブクエリを実行するかカスタムCake find()コールにカスタムSQLを挿入する必要はありません。

0

ゲイリー、あなたのモデルを知らずにこれを答えるのは難しいです。あなたが正しく定義されたスキーマとモデルを持っていると仮定すると、それは比較的簡単であるはずです。

あなたの検索クエリでは、日付別にDESCを注文し、最後の10行を取得します。 (これにより、例えば過去20回の結果が得られます)

結果セットを1つにマージし、DESCで再度並べ替えます。必要なときに文字列をレンダリングするのは簡単なレンダリングロジックです。

+0

私はリレーションなどでモデルを正しく定義していますが、このパスに沿って何かを考えていましたが、レンダリングロジックを記述して配列を結合するのが最も簡単な方法ですが、私の配列にhtmlの大きな塊を持っている。理想的には、ユーザーがコメントしたストーリーと、ユーザーが投稿したストーリーを区別するための方法があります(それぞれの機会にストーリーを外していますが) – GaryDevenay

0

まあ、私は次の関係

ユーザーhasManyの StoryName

ユーザーhasManyのコメント

StoryName hasManyのコメント

0123を作成し、この

ような何かをするだろう件の

コメントbelongsToのユーザー

コメントあなたは

のようなものを持つUserモデルかかわらず、すべての必要なデータを取得する可能性があるための方法は、必要なすべての情報を取得することは本当に簡単だろう belongsToの StoryName

$this->User->recursive = 2; 

$this->User->find('all', $params) *// on $params you could use the conditions that the user retrieved should be friends to the current user* 

このようにすれば、次の構造を持つ配列が得られます。

[USER] [POSTS] [コメント]

し、ビューに渡すとHTML

+0

これは私のモデルなどを設定した方法です今すぐ。しかし、ユーザーがストーリーやコメントを投稿したかどうかを知らせる識別子がないので、私が望むようにデータをどのように表示するかはまだ分かりません – GaryDevenay

0

を作成するために、ビューでのforeachを使用してだけの問題だったあなたならば、私は知りませんあなたはすでに他のモデルセットアップ(ユーザー、ストーリーなど)を持っています。しかし、この点を解明するために、アクティビティモデル(アクティビティテーブル)に焦点を当てます。このテーブルはログテーブルのように使用できます。

単純な表:id、user_id、story_id、created(datetime)、action_type(ストーリーの場合は0、ストーリーのコメントの場合は1)次に、このテーブルをクエリしてアクティビティを検索するだけです。

より一般的な、拡張可能なもの:id、subject_id、subject_type(ユーザーまたは何か動作しているもの)、verb_type、object_id、object_type、created。このモデルを他のモデルにバインドする必要はありません(リレーションシップを指定するときに '条件'を使用することはできますが)、またはその場でbindModelを実行することもできます。

関連する問題