CakePHP:表单输入(呈现为选择)未正确处理 hasOne 关系
Posted
技术标签:
【中文标题】CakePHP:表单输入(呈现为选择)未正确处理 hasOne 关系【英文标题】:CakePHP: form input (rendered as select) does not correctly handle a hasOne relationship 【发布时间】:2013-10-04 10:32:43 【问题描述】:为了澄清我的问题,我想使用 Cakephp 文档中的 Profile User 示例。那里定义的关系是:
个人资料属于用户 用户拥有一个个人资料在数据库中,profiles 表有一个归档的 user_id 用于存储关系。
在大多数示例中,用户在“个人资料”区域中设置或编辑此关系。含义:在配置文件的编辑视图中,有一个输入字段允许为配置文件设置另一个用户。它通过将以下内容放入配置文件/编辑视图中自动工作:
echo $this->Form->input('user_id');
我们权利管理的变化要求我们改变这种关系的设置方式。我们必须将其从 Profiles 区域中取出,而将其呈现在 Users 区域中。
当在 UsersController 中读取用户记录的数据时 ($this->request->data = $this->User->read(null, $id);),CakePHP 自动将 Profile 数据绑定到用户数据(如果存在)。但是,由于 users 表中没有字段 profile_id (因为关系存储在“另一边”),显然 echo $this->Form->input('profile_id'));在用户/编辑视图中不起作用。
我已经了解到,必须首先在 Controller 的编辑操作中构建配置文件列表:
$this->set('profiles', $this->User->Profile->find('list'));
然后让 CakePHP 创建一个选择列表:
echo $this->Form->input('Profile');
但是,似乎缺少一些东西。在我们的例子中,当我查看 CakePHP 创建的 html 输出时,选择列表中的几个选项元素具有 selected 属性集,尽管用户只有一个特定的配置文件,并且该配置文件存储在 $this->data 中。
不知何故,我认为我必须设置一些进一步的选项才能让它工作(如果有办法让它自动工作——也许没有)。
我的意思是我可以设置 Form->input() 调用的 'selected' 属性。由于 CakePHP 创建的表单元素的名称是“data[Profile]”,我不确定 CakePHP 是否会自动正确保存更改,或者我是否必须手动进行。步骤是:
查找将 user_id 设置为当前用户记录的 id 的(以前和现在的)当前配置文件记录,并将该 user_id 设置为 0(或 NULL)。 查找在 data[Profile] 中设置 id 的配置文件,并将其 user_id 设置为当前用户的 id。但是我必须自己做吗,还是我只是错过了一些让 CakePHP 能够做到的事情?
【问题讨论】:
我不确定我是否理解您的要求,但请尝试$this->Form->input('profile_id'))
而不是 $this->Form->input('Profile.id'))
我也遇到了麻烦。您是否要保持 User hasOne Profile 关系?或者您是否尝试修改它以使用户拥有许多个人资料?
感谢您抽出宝贵时间阅读,对于造成的混乱,我深表歉意。我想保持 hasOne 关系。当我之前尝试 $this->Form->input('Profile.id') 时,它没有按预期工作(没有呈现任何内容)。
同时我了解到我必须使用 $profiles 列表(我之前在控制器中设置)明确地提供输入。现在缺少的只是在保存之前在其 user_id 字段中具有 User.id 的配置文件时必须取消设置(或分别设置为 0 或 NULL)。我从用户的选择列表中选择了另一个配置文件,保存后,另一个配置文件在其 user_id 字段中写入了 User.id(这很好),但前一个配置文件的记录保持不变(不太好)。但也许我只需要自己做……
可能被渲染为隐藏输入
【参考方案1】:
我试试
我不认为您真的希望选择输入列出您在数据库中拥有的所有配置文件。
事实上你可以同时编辑你的User
数据和他的Profile
数据:
假设您在配置文件表中有 address
和 phone
字段
您可以在View/User/edit.ctp
中以这种方式构建表单:
echo $this->Form->create('User');
echo $this->Form->input('User.name');
echo $this->Form->input('User.family_name');
echo $this->Form->input('Profile.id'); //this is automatically an hidden field
echo $this->Form->input('Profile.address');
echo $this->Form->input('Profile.phone');
echo $this->Form->close();
在你的控制器中你应该使用
$this->User->saveAssociated($this->request->data);
用户和他的个人资料将被保存在一起
希望这是你想要做的。
【讨论】:
非常感谢您的回答。我知道我可以同时编辑用户和个人资料信息,但这不是我们(或客户)想要的。我们实际上想要一个列出所有配置文件的选择。 Web 应用是一个内网的东西,没有几百万个配置文件,所以列表长度就可以了,我们可以使用 selected.js 使其可搜索。【参考方案2】:我没有发现任何线索表明 CakePHP 会自动执行我需要的操作,所以我按照上面的说明自己做了。保存用户记录时:
查找将 user_id 设置为当前用户记录的 id 的(以前和现在的)当前配置文件记录,并将该 user_id 设置为 0(或 NULL)。 查找在 data[Profile] 中设置了 id 的配置文件,并将其 user_id 设置为当前用户的 id。【讨论】:
以上是关于CakePHP:表单输入(呈现为选择)未正确处理 hasOne 关系的主要内容,如果未能解决你的问题,请参考以下文章