CakePHP在行为中声明模型关联

时间:2014-04-29 22:32:06

标签: cakephp

我正在建立一个“通知”系统,我正在研究一个可通信的行为,我的目标是附加到各种对象 - 帖子,交易,朋友等。虽然我使用在每个模型中声明的手动关联工作,我希望我可以拥有每个模型$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 NotificationNotification 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的声明有关,它将Notification明确地分配给Model,而不是声明Notification模型本身具有该关联,如果这有任何意义的话。< / p>

这有助于澄清问题吗?

修改

我发现,如果我在运行$this->Transaction->create();之前在我的create()内明确地呼叫Notifiable(或NotificationsController上任何其他$this->paginate();模型),正确返回关联。但是,如果我必须在运行查询之前手动创建/声明每个Notifiable对象,那么这会破坏我尝试创建的自动化的目的。

1 个答案:

答案 0 :(得分:1)

我发现当我在一个行为中声明这样的关联时,它似乎更像“自动”工作,就像你想要的那样。遇到与你最近相同的问题。我认为这可能是一个修复。试试吧!

public function setup(Model $Model, $settings = array()) {
    $Model->hasMany = array(
      //set associations here
    );
}