CakePHP 在行为中声明模型关联

问题描述 投票:0回答:1

我正在构建一个“通知”系统,并正在研究一种可通知的行为,我的目标是将其附加到各种对象——帖子、交易、朋友等。虽然我使用每个模型中声明的手动关联来完成此工作,但我希望我可以拥有每个模型

$actsAs Notifiable
并从其中动态声明模型关联。 这将节省相当多的代码行,并使其在未来更具可扩展性。

模型结构差不多是这样的:

Post

id
post_content

Notification

id
type
parent_id

目的是通过说:

Post hasMany Notification WHERE Notification.type = 'Post' AND Notification.parent_id = Post.id
或类似的东西来关联这些模型(以及任何其他“可通知”模型)。

我遇到了问题。 第一个是 SQL 返回错误,指出在引用的模型中找不到关联的列。 第二个是我的

contains()
函数也无法找到关联的模型。

Post Model

class Post extends AppModel {
    public $name = 'Post'
    public $actsAs = array( 'Containable', 'Notifiable' );
}

Notifiable Behavior

    public function setup(Model $Model, $settings = array()) {
    if (!isset($this->settings[$Model->alias])) {
        $this->settings[$Model->alias] = array();
    }
    $this->settings[$Model->alias] = array_merge($this->settings[$Model->alias], $settings);
    $Model->bindModel( array(
        'hasMany' => array(
            'Notification' => array(
                'className' => 'Notification',
                'foreignKey' => 'parent_id',
                'conditions' => array(
                    'Notification.type = "' . $Model->name . '"',
                ),
                'dependent' => true,
            ),
        ),
    ), false );
    $Model->Notification->bindModel( array(
        'belongsTo' => array(
            $Model->name => array(
                'className' => $Model->name,
                'foreignKey' => 'parent_id',
                'conditions' => array(
                    'Notification.type = "' . $Model->name . '"',
                )
            )
        )
    ), false );
}            

我是否以错误的方式处理这个问题和/或者我对行为的理解有点偏差? 我知道,bindModel 将一直工作到请求结束,并将

false
设置为第二个变量。 但是,当在行为中声明时,这些关联是否无法全局访问?

换句话说,如果我有一个

NotificationsController
其中有:

'contain' => array( 
    'Friend',
    'Post',
    'Transaction'
)

如果这些模型

actAs
需要通知,这应该有效吗? 就像我说的,如果我手动声明每个模型中的模型关联,我就可以让它工作。 但对于
Notification
模型来说,这就变得很麻烦,我必须为每个
Notifiable
模型声明它:

$belongsTo = array(
    'ModelAlias' => array(
        'className' => 'Model',
        'foreignKey' => 'parent_id',
        'conditions' => array(
            'Notification.type' => 'Model'
        )
    )
);

因此,就可扩展性而言,我不希望每次添加我认为应该通知的新模型时都必须继续手动声明这些关联。

我希望我已经解释得足够好了。 我仍在掌握 CakePHP,所以如果我的做法有误,请告诉我。

谢谢!

编辑:

简化问题和错误的描述:

我有

Transaction actsAs Notifiable
。 我的
Notifiable
行为的代码仍然如上面所示。 预期的功能是声明
Transaction hasMany Notification
Notification belongsTo Transaction
。 在我的
TransactionsController
中,我尝试使用以下方法对通知模型进行分页:

$this->Paginator->settings = array(
    'contain' => array(
        'Transaction',
    )
    'limit' => 5,
);
$this->notifications = $this->Paginator->paginate( 'Notification' );
$this->set( 'notifications', $this->notifications );

我收到的是一组

Notification
模型,没有附加任何关联的
belongsTo
模型,以及错误:

Notice (8): Undefined index: Transaction [APP/View/Notifications/index.ctp, line 10]

我拥有的每个

Notifiable
模型也会发生同样的情况,除非我在应用程序的其他位置显式实例化它们和/或将其手动附加到
Notifiable
模型。

我觉得这可能与

$Model->Notification->belongsTo
的声明有关,它将通知显式分配给模型,而不是将通知模型本身声明为具有该关联,如果这有意义的话。

这有助于澄清问题吗?

编辑:

我发现,如果我在运行

$this->Transaction->create();
之前在我的
create()
中显式调用
Notifiable
(或任何其他
NotificationsController
模型上的
$this->paginate();
),关联会正确返回。 然而,如果我必须在运行查询之前手动创建/声明每个
Notifiable
对象,这有点违背了我试图创建的自动化的目的。

php cakephp
1个回答
1
投票

我发现当我在行为中声明这样的关联时,它似乎更“自动”地工作,就像你想要的那样。最近遇到了和你一样的问题。我认为这可能是一个解决办法。尝试一下!

public function setup(Model $Model, $settings = array()) {
    $Model->hasMany = array(
      //set associations here
    );
}
© www.soinside.com 2019 - 2024. All rights reserved.