【问题标题】:Using conditions from another model inside a model method using CakePHP在使用 CakePHP 的模型方法中使用来自另一个模型的条件
【发布时间】:2012-04-13 13:05:18
【问题描述】:

在我的应用中,我有三个表:

Users
Profiles
Friends

用户有一个个人资料,个人资料有一个用户和许多朋友。朋友有很多个人资料。

在配置文件模型中,我有一个方法可以获取配置文件的配置文件列表(但它使用来自用户表的相关用户名。)

public function getFriends($username) {

   return $this->find('all', array(
     'conditions' => array(
       'User.username' => $username,
        'Friend.status' => 1
      )
   ));

}

所以它应该得到一个与用户名匹配用户和朋友状态为 1 的个人资料列表。但是我该怎么做呢?

我还将发布我的关联,以便您了解数据库:

用户模型:

public $hasOne = 'Profile';

个人资料模型:

public $belongsTo = 'User';

public $hasMany = array(
    'ProfileFrom'=>array(
        'className'=>'Friend',
        'foreignKey'=>'profile_from'
    ),
    'ProfileTo'=>array(
        'className'=>'Friend',
        'foreignKey'=>'profile_to'
    )
);

public $hasAndBelongsToMany = array(
    'Friendship' => array(
        'className' => 'Profile',
        'joinTable' => 'friends',
        'foreignKey' => 'profile_from',
        'associationForeignKey' => 'profile_to'
    )
);

public $actsAs = array('Containable');

朋友模型:

public $belongsTo = array(
      'UserFrom'=>array(
         'className'=>'Profile',
         'foreignKey'=>'profile_from'
      ),
      'UserTo'=>array(
         'className'=>'Profile',
         'foreignKey'=>'profile_to'
      )
   );

public $actsAs = array('Containable');

【问题讨论】:

  • 它看起来比需要的要复杂一些。为什么用户 HasOne 个人资料?这使得它只是用户的一部分,所以不需要在另一个模型中分离?你不只需要两张表:用户和关系吗?在关系中只需输入friend1_id 和friend2_id 就可以了?
  • 用户不一定有个人资料!但这不是这个问题的重点,而是如何从其他模型中提取条件来设置条件。
  • 哦,这很简单。只要模型有关系,就可以通过$this-> Comment->someMethod() 访问其他方法和属性(假设 Post hasMany Comment,示例代码位于 Post 模型中)

标签: php cakephp


【解决方案1】:

这看起来很复杂,我建议看一下 Containable(一种核心 cakephp 行为),它可以更轻松地选择要获取的数据(尤其是在防止选择过多数据方面)。请考虑将其用于您的整个应用。

您似乎正试图告诉 cake 在关联的 Friend 模型中进行搜索,但如果我是对的,则该朋友存在的唯一关联将别名为 ProfileTo 和 ProfileFrom。所以我猜蛋糕不知道该去哪里招惹“朋友”。但在未来,发布任何错误也会有所帮助。

请参阅下面我的建议以获取可能的解决方法。


现在您可以执行以下操作: 在 ProfileModel 中:

function getFriends($username) {
    //Start by getting User's ID
    $user = $this->User->find(
        'first',
        array(
            'conditions' => array(
                'User.username' => $username
            )
        )
    );
    //User's ID is now $user['User']['id']

    //Fetch user's profile with associated friends
    $this->Behaviors->attach('Containable');
    $profileAndFriends = $this->find(
        'first',  //Because User hasOne Profile, so we'll fetch this one profile.
        array(
            'conditions' => array(
                'Profile.user_id' => $user['User']['id']
            ),
            //We'll want to fetch all associated Friend records (which are linked to the Profile model as ProfileFrom and ProfileTo
            'contain' => array(
                'ProfileFrom' => array(
                    'conditions' => array(
                        'status' => 1
                    )
                ),
                'ProfileTo' => array(
                    'conditions' => array(
                        'status' => 1
                    )
                )
            )
        )
    );
    return $profileAndFriends;
}

它应该像这样工作。所以在 FriendsController 中你现在应该能够做到$this->Friend->UserTo->getFriends('cameron'); 这应该获取属于用户名为“cameron”的用户的个人资料,以及与此个人资料关联的所有朋友。


还有一件小事仍然困扰着我,那就是您收到一个错误,指出 ProfileTo 与 Profile 没有关联,这很奇怪,因为在您的示例中,关系显然已定义。 原因可能是您的关联定义中的错误,但我不确定。


还有一个建议,如果上面的代码不起作用,请将contain数组替换为:

            'contain' => array(
                'Friendship' => array(
                    'conditions' => array(
                        'OR' => array(
                            'Friendship.profile_from' => 'Profile.id',
                            'Friendship.profile_to' => 'Profile.id',
                        )
                    )
                )
            )

【讨论】:

  • 你为什么用'first'而不是'all'?
  • 该代码也给了我这个错误:Warning (512): Model "Profile" is not associated with model "ProfileTo" [CORE/Cake/Model/Behavior/ContainableBehavior.php, line 339]
  • 我使用了“第一”,因为用户只有一个配置文件。所以我会获取该个人资料,以及所有相关的朋友。不过,您报告的错误不应该发生,因为您已经在 ProfileModel 中定义了与 ProfileTo 的关联,它仍然存在,对吗?
  • 等一下,您使用的是哪个 CakePHP 版本?我假设是 1.3,但你错误中的路径看起来更像 2.0...
  • 我对代码示例做了一个小的更新。我真的不明白它是如何导致错误的,但你永远不知道......你能重试吗?
猜你喜欢
  • 2012-02-27
  • 2012-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多