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' =&gt; 'companystatus' 是多余的。您可以安全地移除该部分。

但实际上,这完全是您的问题所附带的,它存在于最后一次 ORM 调用和您的数据库之间的某个地方。 (我在这里假设hasbeendeletedcompany 表中的一列,而不是您提到的其他两个表中的任何一个。如果不是这样,请告诉我。)

如果您同时使用-&gt;where('id', '=', 1)-&gt;find(),您真的希望返回数据库中存在的一条公司记录。我建议单独检查hasbeendeleted

说到这个,与其将变量命名为$companies,不如将​​其命名为单数(例如$company),因为它只会保存一条记录。

您可以将ORM::factory('company')-&gt;where('id', '=', 1) 简化为ORM::factory('company', 1)

如果您知道确定存在数据库 ID 为 1 的公司,则以下代码应返回该记录:

$myCompany = ORM::factory('company', 1);

然后你可以做类似if ( ! $myCompany-&gt;hasbeendeleted) ...

这应该对您有所帮助。如果您遇到麻烦,请发布更多详细信息。

【讨论】:

感谢您,从清洁的角度来看,您的 cmets 非常出色。但是,问题是在将关系设置为原始帖子时,我没有获得 CompanyStatus 或 CompanyType 记录。那是我的问题。我希望 Kohana ORM 为我处理这个问题,而不是进行 3 次 DB 调用(公司,然后是状态和类型记录)。 @Dominik 您是否在您的Model_CompanyStatusModel_CompanyType 中设置了$_has_many 以将它们链接到Model_Company? (我假设您正在尝试在状态/类型和公司之间实现一对多的关系。) 再次嗨(再次感谢您抽出宝贵时间),是的,我在 Model_CompanyStatus 和 Model_CompanyType 文件中有 $_has_many。调用ORM方法获取单个公司时,是否需要调用获取关联的公司类型和状态?我试过 $company->companystatus->find();,但是这并没有返回基于公司记录的值,它似乎只是获取第一条记录,或者只在视图中显示第一条记录。 @Dominik 嗯...我必须查看Model_CompanyStatusModel_CompanyType 的代码(变量,不一定是任何方法),以提供进一步的帮助。您可以将其添加到您的问题中吗?另外,请更新那里的任何现有代码,以反映您在发布此问题后可能所做的任何更改。 @Dominik 我还需要简要描述三个相关数据库表的主要部分(至少表名、主键和您尝试使用的任何其他部分,例如hasbeendeleted).

以上是关于Kohana 3 ORM 关系问题的主要内容,如果未能解决你的问题,请参考以下文章

Kohana-v3 ORM 父关系

如何在 Kohana 3 中链接多个 ORM 关系?

Kohana 3 ORM:如何使用 2 个多对多关系执行查询

Kohana 3 ORM - 使用静态方法连接和 has_many 关系

如何在 Kohana 3 ORM 关系中指定两个键

Kohana3 ORM 需要澄清关系