2012-05-01 10 views
0

ここに誰かが私を助けることができると確信しています。まず、私がやっていることについての少しの背景を離れて。私は基本的にソーシャルネットワーキングサイトを構築しています。これは簡単に理解できるように、基本的に誰もが好きなFacebookのモックと呼んでいます。コントローラ内の検索操作からの爆縮値の処理

現在、1つのことを除いてすべて正常に動作しています。その1つは、私の友人の投稿をすべて「壁」に表示していることです。私は自分の投稿を得ることができ、私は要求された友人と私を要求した友人の両方からIDが最も低い人の投稿を得ることもできます。

たとえば、私はユーザーAであり、ユーザーB、ユーザーC、ユーザーDおよびユーザーEが存在するとします。ユーザーBとユーザーCの両方にログインし、両方を承認します。ユーザーDとユーザーEが私に要求し、両方を承認すると仮定しましょう。だから私(ユーザA)はユーザB、C、D、Eと友達です。私はBとCを要求し、DとEは私にリクエストしました。この例では、これらのユーザーのIDが順番に並んでいると仮定します。 1は私(A)であり、5はEである。

私は自分の投稿を取得するが、これは期待されるべきだが、ユーザーB(私が要求した)とユーザーD私を要請した)。ユーザーのCとEの投稿は、IDがBとDの後にあるため表示されません。

これで、関連モデルはUser、Friendship and WallPostです。私のusers_controllerは、profile()関数で次のfind操作を行います。私はこの上で与えた例に

文脈では
$friends_to = $this->Friendship->find('all', array(
      'conditions' => array('Friendship.pending' => 1, 'Friendship.approved' => 1, 'UserTo.id' => $id), 
      'fields' => array('Friendship.user_from') 
     ) 
    ); 
    $friends_to_ids = implode(',', Set::extract($friends_to, '{n}.Friendship.user_from')); 

    $friends_from = $this->Friendship->find('all', array(
      'conditions' => array('Friendship.pending' => 1, 'Friendship.approved' => 1, 'UserFrom.id' => $id), 
      'fields' => array('Friendship.user_to') 
     ) 
    ); 
    $friends_from_ids = implode(',', Set::extract($friends_from, '{n}.Friendship.user_to')); 

    $post_conditions = array(
     'OR' => array(
      array('WallPost.user_id' => $this->Auth->user('id')), 
      array('WallPost.user_id' => $friends_to_ids), 
      array('WallPost.user_id' => $friends_from_ids) 
     ), 
    ); 
    $posts = $this->WallPost->find('all', array(
      'conditions' => $post_conditions, 
      'order' => array('WallPost.created' => 'desc') 
     ) 
    ); 
    $this -> set ('posts', $posts); 

次のSQL文を返しますが:

SELECT `WallPost`.`id`, `WallPost`.`user_id`, `WallPost`.`content`, `WallPost`.`created`, `WallPost`.`modified`, `User`.`id`, `User`.`first_name`, `User`.`last_name`, `User`.`username`, `User`.`password`, `User`.`email`, `User`.`group_id`, `User`.`confirmed`, `User`.`confirm_code`, `User`.`created`, `User`.`modified` FROM `wall_posts` AS `WallPost` LEFT JOIN `users` AS `User` ON (`WallPost`.`user_id` = `User`.`id`) WHERE ((`WallPost`.`user_id` = 1) OR (`WallPost`.`user_id` = '2,3') OR (`WallPost`.`user_id` = '4,5')) ORDER BY `WallPost`.`created` desc 

ので、IDがあるだけで、次が表示されます。 (WallPostuser_id = 1)、IDが1のユーザー(WallPostuser_id = '2,3')、ユーザーID 2のみが表示されます。 (WallPostuser_id = '4,5')、ユーザーID 4のみが表示されています。

私はここで間違っていますか?これらのすべてのユーザーの結果が表示されないのはなぜですか?正しい方向へのプッシュは大いに感謝されます。

クイックアップデート:クエリを再構成して、少し違うが同じことを返すようにしました。それは2,3 '、それはのようにすべてのもの(1,2,3として、それらを閲覧する必要がある文字列として「4,5」を見ているかのように見えるもう少し研究した後

SELECT `WallPost`.`id`, `WallPost`.`user_id`, `WallPost`.`content`, `WallPost`.`created`, `WallPost`.`modified`, `User`.`id`, `User`.`first_name`, `User`.`last_name`, `User`.`username`, `User`.`password`, `User`.`email`, `User`.`group_id`, `User`.`confirmed`, `User`.`confirm_code`, `User`.`created`, `User`.`modified` FROM `wall_posts` AS `WallPost` LEFT JOIN `users` AS `User` ON (`WallPost`.`user_id` = `User`.`id`) WHERE `WallPost`.`user_id` IN (1, '2,3', '4,5') ORDER BY `WallPost`.`created` desc 

、 4,5)。どのように私はこれを修正することができます私に来ることはできません、再び任意の援助に感謝されます。

正解であった助けをいただきありがとうございました。今ここに私のこの小さな問題があります。

DBから引き出されるものは、3つのもの、自分のユーザーID、要求され、承認されたフレンドIDと、要求され、承認されたフレンドのIDを含む2つの配列に対して照会されます。以下の解決法で与えられているのと同じテクニックを使用しています。私に$ friends_to_ids =(2,3)と$ friends_from)、IDSの=を与える

$friends_tos = $this->Friendship->find('all', array(
      'conditions' => array('Friendship.pending' => 1, 'Friendship.approved' => 1, 'UserTo.id' => $id), 
      'fields' => array('Friendship.user_from'), //array of field names 
     ) 
    ); 
    $friends_to_ids = Set::extract($friends_tos, '{n}.Friendship.user_from'); 

    $friends_froms = $this->Friendship->find('all', array(
      'conditions' => array('Friendship.pending' => 1, 'Friendship.approved' => 1, 'UserFrom.id' => $id), 
      'fields' => array('Friendship.user_to'), //array of field names 
     ) 
    ); 
    $friends_from_ids = Set::extract($friends_froms, '{n}.Friendship.user_to'); 

(4,5)、私はその後、私に$ aMerge =(2,3与えるそれらを結合するために、次の$aMerge = array_merge($friends_to_ids, $friends_from_ids);を使用し、 4,5)、それは素晴らしいです。

しかし、私の検索条件としてこれを使用して:

$post_conditions = array(
     'OR' => array(
      'WallPost.user_id' => $this->Auth->user('id'), 
      'WallPost.user_id' => $aMerge 
     ), 
    ); 

はたったの$ aMergeの値を返し、完全に私のユーザIDの値をスキップします。私はこの状態を再構築するための複数の方法を試みましたが、無駄です。私はそれがどのようなこと通常であるように私は小さな何かが欠けていると確信しているが、私はので、多分...

が、私はそれをマークすることができますどこに答えることを確認してください...

+2

条件は '' field '=>' 2,3''ではなく '' field '=> array(2,3) 'を呼び出すので、' Set :: extract'の結果を使用するだけで、それを暗黙に指定する必要はありません。 – ori

+0

@oriが正しいです。配列を渡すことで、CakeはSQLに 'IN'文を生成します。 – jeremyharris

+0

@ori:誰かがする前にそれを答えにする方が良いです。私のように;) –

答えて

0

OKを空白を描いていますそれは一番きれいな方法ではありませんが、私は考えを持って試してみました。誰かがよりシンプルでクリーンなソリューションを持っているなら、私はそれが何であるかを知っていることに感謝します。

これは私がしたことです。友人を見つけるのと同じ流れに従って、私は自分自身を見つけ出し、「すべて」を見つけ出して1に戻すことを制限しました。そして、それが単一の値であっても、配列の形でそのIDを抽出します。私はその後、array_mergeにあることを追加しました

$me = $this->User->find('all', array(
      'conditions' => array('User.id' => $this->Auth->user('id')), 
      'fields' => array('User.id'), 
      'limit' => 1, 
     ) 
    ); 
    $my_id = Set::extract($me, '{n}.User.id'); 

$aMerge = array_merge($my_id, $friends_to_ids, $friends_from_ids); 

その後、私はリターンを得た「壁」のポストのための私の検索条件として$ aMergeを使用した場合(1,2,3,4- 、5)これは私が必要としていたものです。また、あなたの答えを教えてください。

関連する問題