【问题标题】:Bug in Kohana 3 ORM?Kohana 3 ORM 中的错误?
【发布时间】:2010-12-13 00:09:39
【问题描述】:

很抱歉问了关于 Kohana 的所有这些问题。他们通常会被忽略。我想我刚刚发现了一个错误。我正在连接两个不直接相关的表。

$results = ORM::factory('foo')->join("bar")->on("foo.foreign_id", "=", "bar.id");

这会生成一个不明确解析表名的查询:

SELECT * FROM `foo` JOIN `bar` ON (`foo`.`foreign_id` = `bar`.`id`)

这给了(在 phpMyAdmin 中)一个如下所示的表:

id    time          foreign_id      blah_int    id  baz
4     1291851245    3           0               3   52501504

注意有两个id 列,一个用于foo 表,一个用于bar。这是一个真正的问题。因为现在,在我的结果中,如果我循环...

foreach ($results as $result) {
    echo $result->id;    // prints 3!!!
}

因为我的结果应该是 foo 对象,所以我希望得到 4 的 id,但由于加入,它给了我 3。这是 ORM 库中的错误吗?我应该使用不同的方法来限制我的查询结果吗?我真的不想做两个单独的查询,我加载所有bars id,然后以这种方式加载我的foos,但看起来我必须这样做。

【问题讨论】:

  • 你试过ORM关系(kohanaframework.org/guide/tutorials.orm)吗?像 foreach($foo->bars as $bar) {...}
  • 这些表不相关,除非是间接相关。他们与另一个表共享关系。所以我的替代方法是先从表中加载共同的 id,但我宁愿不这样做。

标签: orm kohana-3 kohana-orm


【解决方案1】:

您必须使用 Database 对象来构建原始查询,而不是 ORM,如下所示:

$results = DB::select()->from('foo')->join('bar')->on("foo.foreign_id", "=", "bar.id")->execute();

您将需要指定一些列别名以使您的查询正常工作,除非您按预期使用 ORM。

使用 ORM

如果你想使用 ORM,你需要在你的模型中定义关系。您提到他们与另一个表共享关系,因此在您的情况下,您可以像这样使用 has many through 关系:

protected $_has_many = array(
    'bars' => array('model' => 'bar', 'through' => 'other_table', 'foreign_key' => 'foreign_id'),
    );

尽管您给出的示例表明直接的 has_many 关系会起作用:

protected $_has_many = array(
    'bars' => array('model' => 'bar','foreign_key' => 'foreign_id'),
    );

这将允许您使用类似的语句访问所有条形图

$bars = $results->bars->find_all();
foreach($bars as $bar)
{
    echo $bar->id; // should echo 4, assuming one record in bars with id 4
}

如果您想了解更多关于 ORM 和关系的信息,Kohana 3.1 ORM Reference Guide 是一个很好的起点

使用 Kohana 数据库对象和查询构建器

如果您更喜欢临时查询并使用查询构建器进行连接,无论您使用的是 Kohana 还是只是原始查询,您都可能会遇到列名冲突(pop "SELECT * FROM foo JOIN bar ON (@ 987654329@.foreign_id = bar.id)" 进入 MySQL,你会得到完全相同的结果。

Kohana,就像 MySQL 一样,正是出于这个原因,您可以定义列别名。 (见here for more information)

按如下方式重写您的查询:

$results = DB::select('id', 'time', 'foreign_id', array('bar.id', 'bar_id'), 'baz')->from('foo')->join("bar")->on("foo.foreign_id", "=", "bar.id")->execute();

这将返回:

id    time          foreign_id      blah_int    bar_id   baz
4     1291851245    3               0           3        52501504

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-02
    • 1970-01-01
    • 2012-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多