我正在开始一个cakephp应用程序,我从来没有在现实世界中使用它所以我有点困惑HABTM如何工作,即使我阅读文档我甚至无法得到$this->User->Subscription
和没有看到任何额外的物品被倾倒
我想要的是在用户和订阅之间创建HATBM
所以我创建了三个表(用户,订阅,users_subscribers)
然后在我的User.php
模型中我做了这个
var $hasAndBelongsToMany =
array(
'Subscription' =>
array('className'=>'Subscription',
'joinTable' => 'users_subscribers',
'foreignKey' => 'user_id',
'associationForeignKey' => 'subscription_id',
'unique' => true,
)
);
SUbscription.php
var $hasAndBelongsToMany = array(
'User'=>array('className'=>'User',
'joinTable' => 'users_subscribers',
'foreignKey' => 'subscription_id',
'associationForeignKey' => 'user_id',
'unique' => true));
即使有标签示例并且跟随它,我也无法获得关系集,我还添加了行<?php echo $this->element('sql_dump'); ?>
以查看它是否正在运行它不是......
有人可以指导我如何让HATBM正常工作,还需要验证哪些内容?
完整代码: pages_controller.php http://sao.pastebin.com/PWQMhE2z
用户模型: http://sao.pastebin.com/PWqwAj1v
订阅模式: http://sao.pastebin.com/MfVFR4Kw
订阅SCHEMA: http://sao.pastebin.com/mLRcEp1c
用户SCHEMA: http://sao.pastebin.com/UeTRHh3u
users_subscriptions SCHEMA: http://sao.pastebin.com/4UeSDZte
答案 0 :(得分:4)
实现这项工作的最简单,最快捷的方法是遵循CakePHP的配置规则而不是自定义。
这意味着遵循CakePHP约定,除非你有充分的理由不这样做。
我强烈建议您从已知的基本设置开始,然后根据需要进行修改。这是一种快速简便的启动和运行方式。
数据库表
从三个数据库表开始:users,subscriptions和subscriptions_users。你已经拥有的模式还可以,但我会做一些修改以确保顺利进行:
name
或title
列添加到users
表。要么是这样,要么您必须将$displayField
属性添加到您的用户模型中。如果你不这样做,你会错过CakePHP提供的一些“自动化”。 More info on $displayField subscriptions_users
。这是CakePHP的惯例,没有理由不节省时间和担心跟随它。 : - )CREATE TABLE subscriptions_users ( subscription_id int(11) NOT NULL, user_id int(11) NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
请注意,没有定义任何键。从CakePHP手册:“为避免任何问题 - 不要为这两个字段定义组合主键,如果您的应用程序需要它,您可以定义唯一索引。”
模特
尽量保持代码清洁。 CakePHP中实现了许多合理的默认值,并且在定义它们时没有必要定义它们。
以下型号适合您:
<强> user.php的强>
<?php
class User extends AppModel {
var $hasAndBelongsToMany = array('Subscription');
}
?>
<强> subscription.php 强>
<?php
class User extends AppModel {
var $hasAndBelongsToMany = array('User');
}
?>
非常简单。只需确保您的模型文件名称正确:user.php和subscription.php,全部小写。
另外,请注意,您不必设置任何关系选项(className
,joinTable
等),除非它们必须是默认值之外的其他选项。百分之九十的默认值应该可以为你服务。
你应该立即开始运作。您可以确保正在加载模型对象,并且可以在控制器中访问它们,如下所示:
<强> users_controller.php中强>
<?php
class UsersController extends AppController {
var $name = 'Users';
function index() {
$this->autoRender = false;
var_dump(is_object($this->User));
var_dump(is_object($this->User->Subscription));
}
}
?>
<强> subscriptions_controller.php 强>
<?php
class SubscriptionsController extends AppController {
var $name = 'Subscriptions';
function index() {
$this->autoRender = false;
var_dump(is_object($this->Subscription));
var_dump(is_object($this->Subscription->User));
}
}
?>
/ users和/ subscriptions的输出都应为bool(true) bool(true)
。
您可以通过执行pr($this->User);
来查看完整模型。
删除记录
如果使用例如$this->User->delete($user_id)
删除单个记录,则连接表中具有该用户ID的所有记录也将自动删除。
如果要从HABTM连接表中删除单个记录,而不删除它链接到的记录,实际上“取消连接”这两个记录,则可以通过SubscriptionsUser模型执行此操作。这是一个在有HABTM关系的情况下即时创建的模型。
请点击此处查看示例:CakePHP hasAndBelongsToMany (HABTM) Delete Joining Record
答案 1 :(得分:1)
我做了一个带有基本架构的测试应用程序,我得到了所有关系。我怀疑你的困境与你所做的事实有关$uses = array('User', 'Subscription');
为什么不尝试使用$uses = $uses = array('User');
然后尝试
$this->User->find('all');
$this->User->Subscription->find('all');
答案 2 :(得分:0)
您还需要在Subscription.php
模型中定义相同的HABTM关系。如果我没记错的话,CakePHP会在内部从其他方面的HABTM配置中提取一些必要的信息。
答案 3 :(得分:0)
我总是使用两个“hasMany”关系和一个“belongsTo”关系来获得CakePHP中更多控件的HABTM效果。
试试这个:
用户模型(user.php)
class User extends AppModel {
public $name = 'User';
public $actsAs = array('Containable');
public $hasMany = array('UserSubscription');
}
订阅模型(subscription.php)
class Subscription extends AppModel {
public $name = 'Subscription';
public $actsAs = array('Containable');
public $hasMany = array('UserSubscription');
}
UserSubscription模型(user_subscription.php)
class UserSubscription extends AppModel {
public $name = 'UserSubscription';
public $belongsTo = array('User','Subscription');
}
pages / home action(pages_controller.php)
public function home() {
$data = array(
'User' => array(
'id' => 1, 'user_email' => 'allenskd@gmail.com', 'user_password' => 'fdfdkert', 'user_salt' => 'haha', 'user_displayname' => 'David'
),
'UserSubscription' => array(
'user_id' => '1', 'subscription_id' => '1'
),
'Subscription' => array(
'id' => 1, 'title' => 'My first plan', 'price' => '30.00', 'subscriber_count' => '1'
),
);
$this->Subscription->save($data);
$this->User->saveAll($data);
$test = $this->User->find('all', array('contain' => array('UserSubscription' => array('Subscription'))));
pr($test);
}