Kohana 3 ORM 关系问题
Posted
技术标签:
【中文标题】Kohana 3 ORM 关系问题【英文标题】:Kohana 3 ORM Relationships Question 【发布时间】:2011-05-09 05:50:24 【问题描述】:我浏览过几个站点(包括这个站点),不幸的是,作为一个 Kohana 新手,我仍然无法使用它。数据关系比较简单,我有一个公司记录,应该关联1个状态记录和1个类型记录。当然,表中会有多家公司,但每家公司只允许链接到每个公司中的一个(并且必须是)。
我拥有的是:
class Model_Company extends ORM
protected $_has_one = array(
'companystatus' => array('model' => 'companystatus', 'foreign_key' => 'entryid'),
'companytype' => array('model' => 'companytype', 'foreign_key' => 'entryid')
,
);
公司状态模型:
<?php defined('SYSPATH') or die('No direct access allowed.');
class Model_CompanyStatus extends ORM
protected $_table_name = 'datadictionary';
protected $_primary_key = 'entryid';
protected $_has_many = array(
'company' => array('foreign_key' => 'statusid')
,
);
?>
公司类型模型:
<?php defined('SYSPATH') or die('No direct access allowed.');
class Model_CompanyType extends ORM
protected $_table_name = 'datadictionary';
protected $_primary_key = 'entryid';
protected $_has_many = array(
'company' => array('foreign_key' => 'companytypeid')
,
);
?>
companystatus 和 companytype 模型映射到具有 2 个字段(entryid 和 entryname)的单个表。此表称为“datadictionary”,具有适当的属性,因此我不必使用“id”作为记录 id 字段。
现在我像这样加载我的公司记录:
$company = ORM::factory('company')
->where('id', '=', 1)
->where('hasbeendeleted', '=', 0)
->find();
问题是我没有为公司的 companystatus 和 companytype 属性返回任何东西,当我执行 $company->companystatus->find() 时,我得到了返回的第一条记录,这很奇怪。我错过了什么?
谢谢!!
:-)
编辑: 为简单起见,Company 表包含以下字段:
ID (primary key) - auto inc int
CompanyName - varchar(255)
StatusID - int
CompanyTypeID - int
HasBeenDeleted - smallint (0 for false, 1 for true)
数据字典表:
EntryID (primary key) - auto inc int
EntryName - nvarchar(255)
公司记录示例:
ID: 1
CompanyName: TestCompany
StatusID: 1
CompanyTypeID: 3
HasBeenDeleted: 0
DataDictionary 记录示例:
EntryID: 1
EntryName: Active
EntryID: 2
EntryName: Inactive
EntryID: 3
EntryName: Customer
EntryID: 4
EntryName: Supplier
【问题讨论】:
【参考方案1】:这里有几件事我会尝试改变。
首先,为了可读性,大多数人在外键中使用下划线。因此,我建议不要使用entryid
,而是使用entry_id
(您必须同时更改数据库和代码)。
在 Kohana 3 中,当键与模型名称相同时,在 $has_one
数组中声明 'model' => 'companystatus'
是多余的。您可以安全地移除该部分。
但实际上,这完全是您的问题所附带的,它存在于最后一次 ORM 调用和您的数据库之间的某个地方。 (我在这里假设hasbeendeleted
是company
表中的一列,而不是您提到的其他两个表中的任何一个。如果不是这样,请告诉我。)
如果您同时使用->where('id', '=', 1)
和->find()
,您真的希望返回数据库中存在的一条公司记录。我建议单独检查hasbeendeleted
。
说到这个,与其将变量命名为$companies
,不如将其命名为单数(例如$company
),因为它只会保存一条记录。
您可以将ORM::factory('company')->where('id', '=', 1)
简化为ORM::factory('company', 1)
如果您知道确定存在数据库 ID 为 1 的公司,则以下代码应返回该记录:
$myCompany = ORM::factory('company', 1);
然后你可以做类似if ( ! $myCompany->hasbeendeleted) ...
这应该对您有所帮助。如果您遇到麻烦,请发布更多详细信息。
【讨论】:
感谢您,从清洁的角度来看,您的 cmets 非常出色。但是,问题是在将关系设置为原始帖子时,我没有获得 CompanyStatus 或 CompanyType 记录。那是我的问题。我希望 Kohana ORM 为我处理这个问题,而不是进行 3 次 DB 调用(公司,然后是状态和类型记录)。 @Dominik 您是否在您的Model_CompanyStatus
和Model_CompanyType
中设置了$_has_many
以将它们链接到Model_Company
? (我假设您正在尝试在状态/类型和公司之间实现一对多的关系。)
再次嗨(再次感谢您抽出宝贵时间),是的,我在 Model_CompanyStatus 和 Model_CompanyType 文件中有 $_has_many。调用ORM方法获取单个公司时,是否需要调用获取关联的公司类型和状态?我试过 $company->companystatus->find();,但是这并没有返回基于公司记录的值,它似乎只是获取第一条记录,或者只在视图中显示第一条记录。
@Dominik 嗯...我必须查看Model_CompanyStatus
和Model_CompanyType
的代码(变量,不一定是任何方法),以提供进一步的帮助。您可以将其添加到您的问题中吗?另外,请更新那里的任何现有代码,以反映您在发布此问题后可能所做的任何更改。
@Dominik 我还需要简要描述三个相关数据库表的主要部分(至少表名、主键和您尝试使用的任何其他部分,例如hasbeendeleted
).以上是关于Kohana 3 ORM 关系问题的主要内容,如果未能解决你的问题,请参考以下文章
Kohana 3 ORM:如何使用 2 个多对多关系执行查询