Kohana 3 ORM 中的错误?

发布于 2024-10-07 22:37:10 字数 863 浏览 3 评论 0原文

很抱歉问有关 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 表和一个。这是一个真正的问题。因为现在,在我的结果中,如果我循环...

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

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

Sorry to ask all these questions about Kohana. They usually get ignored. I think I just found a bug. I'm making a join between two tables that are not directly related.

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

This generates a query that does not resolve the table names explicitly:

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

Which gives (in phpMyAdmin) a table that looks like this:

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

Notice there are two id columns, one for the foo table and one for bar. This is a real problem. Because now, in my results, if I loop through...

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

Because my results should be foo objects, I expect to get an id of 4, but it's giving me 3 because of the join. Is this a bug in the ORM library? Should I be using a different method to restrict my results from the query? I really don't want to do two separate queries where I load all the bars id's, and then load my foos that way, but it looks like I have to.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

心房的律动 2024-10-14 22:37:10

您必须使用 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'),
    );

这将允许您使用以下方式访问所有栏 如果您想学习,像 Kohana 3.1 ORM 参考指南这样的声明

$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 数据库对象和查询构建器

如果您更喜欢即席查询并使用查询构建器进行联接,那么无论您使用 Kohana 还是只是原始的,您都可能会遇到列名称冲突查询 (pop "SELECT * FROM foo JOIN bar ON (foo.foreign_id = bar.id)” 到 MySQL 中,您将得到完全相同的结果)。

Kohana,就像 MySQL 一样,正是出于这个原因允许您定义列别名。 (请参阅此处了解更多信息

重写您的查询如下:

$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

You have to use the Database object to build raw queries, not ORM, like this:

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

You will need to specific some column aliases however to make your query work unless you use ORM as it was intended.

Using ORM

If you want to use ORM, you need to define the relationships in your model. You mention that they share a relationship with another table so in your case you could use a has many through relationship like this:

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

Although your example as given suggests that a straight has_many relationship would work:

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

This would allow you to access all of the bars using a statement like

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

The Kohana 3.1 ORM Reference Guide is good place to start if you want to learn more about ORM and relationships

Using the Kohana database object and query builder

If you prefer ad hoc queries and are doing joins using the query builder you will likely have colliding column names regardless if you are using Kohana or just raw queries (pop "SELECT * FROM foo JOIN bar ON (foo.foreign_id = bar.id)" into MySQL and you will get the exact same result).

Kohana, just like MySQL allows you to define column aliases for precisely this reason. (See here for more information)

Rewrite your query as follows:

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

This will return:

id    time          foreign_id      blah_int    bar_id   baz
4     1291851245    3               0           3        52501504
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文