Love Fuel?    Donate

FuelPHP Forums

Ask your question about FuelPHP in the appropriate forum, or help others by answering their questions.
ORM with related limit at wrong place?
  • $my_level = \Model_AccountLevel::query()->related(array('account_level_group'))->where('account_id', $account_id)->order_by('account_level_group.level_priority', 'ASC')->get_one();

    i got this query from above php.
    SELECT `ws_t0`.`level_id` AS `t0_c0`, `ws_t0`.`level_group_id` AS `t0_c1`, `ws_t0`.`account_id` AS `t0_c2`, `ws_t1`.`level_group_id` AS `t1_c0`, `ws_t1`.`level_name` AS `t1_c1`, `ws_t1`.`level_description` AS `t1_c2`, `ws_t1`.`level_priority` AS `t1_c3` FROM (SELECT `ws_t0`.`level_id`, `ws_t0`.`level_group_id`, `ws_t0`.`account_id` FROM `ws_account_level` AS `ws_t0` WHERE `ws_t0`.`account_id` = 2 LIMIT 1) AS `ws_t0` LEFT JOIN `ws_account_level_group` AS `ws_t1` ON (`ws_t0`.`level_group_id` = `ws_t1`.`level_group_id`) ORDER BY `ws_t1`.`level_priority` ASC

    It was limit 1 but NOT at the end of query and because of this i got the max(DESC) value instead of min value.

  • my table data

    account_level_group
    level_group_id | level_name | level_description | level_priority
    1 | Super administrator | For site owner or super administrator. | 1
    2 | Administrator | NULL | 2
    3 | Member | For registered user. | 999
    4 | Guest | For non register user. | 1000

    account_level
    level_id | level_group_id | account_id
    1 | 4 | 0
    2 | 1 | 1
    3 | 3 | 2
    5 | 3 | 4
    9 | 2 | 2
    14 | 3 | 5
    16 | 1 | 6
    17 | 1 | 7

    the result from order ASC was correct if i use get();
    but if i use get_one(); the result show only max value item.
  • This is documented and by design.

    ORM will always try to return complete resultsets based on the query you construct. In this case you're asking for "account_level" with account_id 2 and all it's groups (because you do a get()).

    You don't specify anywhere that you only want one row returned, for that you need to add ->rows_limit(1). See the docs on the difference between limit() and rows_limit().
  • i was copy wrong code.
    the get() really is get_one() and the query has LIMIT 1 inside the query from the example above.
  • HarroHarro
    Accepted Answer
    That is by design, and documented. This is because it's a get_one, with relations.

    Say you have 1 parent, and 5 children. The ORM will fetch them all, so you'll end up with one Model_Parent object (since you asked for one), and all five Model_Child objects.

    If you apply the limit to the outer query, you'll get one Model_Parent object, and only one Model_Child object (since you have limited the entire join).

    Because ORM caches, you now have an incomplete relation, and no way to get the remaining 4 Model_Child objects. So if one bit of your code would have done your version of limit, and somewhere else in your code you try to do an operation on the children, you'll end up with inconsistent results.

    If you absolutely know what you are doing (and you do now ;-) you can work around this by using ->rows_limit(1) and a get(). Which will use an outside limit of 1.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion