Love Fuel?    Donate

FuelPHP Forums

Ask your question about FuelPHP in the appropriate forum, or help others by answering their questions.
ORM Method chaining
  • Hi, I don't know if this is a bug or my usage of ORM chaining with order_by() but with no where() clause which is causing my issue. The docs state:
    $query = Model_Article::find()->where('category_id', 1)->order_by('date' => 'desc');
    

    I thought it was a simple typo error as it indicates that order_by is expecting an array to be passed suggested by the usage or the => operator. I added the array statement but got an empty result when I tried:
    $data['results'] = Model_Blog::find()->order_by(array('blog_date' => 'desc'));
    

    I then looked at the ORM query.php class and tried this:
    $data['results'] = Model_Blog::find()->order_by('blog_date', 'desc');
    

    I then got this error:
    Fuel\Core\Fuel_Exception [ Error ]: Object class was not whitelisted in security.whitelisted_classes and could not be converted to string.
    
    COREPATH/classes/security.php @ line 180
    

    This however works fine:
    $data['results'] = Model_Blog::find('all', array(
         'order_by' => array('blog_date' => 'desc')
     ));
    

    Am I missing something? Phil.
  • You can not pass objects directly to views, the security class will prevent that by trying to convert it to string. Which fails if the object doesn't have a __toString() method. Use the View's set() method with the second parameter set to 'false' to pass variables to a view without a security check. With regards to the order_by() issue, -> order_by( array('field' => 'ASC') ) is correct. Can you enable the profiler (in app/config/config.php AND app/config/db.php) and check what query is produced when you use this?
  • Hi, Profiling turned on in both config and db. One query is run if I use
    $data['results'] = Model_Blog::find('all', array(
         'order_by' => array('blog_date' => 'desc')
     ));
    
    Query run
    SELECT `t0`.`id` AS `t0_c0`, `t0`.`title` AS `t0_c1`, `t0`.`post` AS `t0_c2`, `t0`.`blog_date` AS `t0_c3` FROM `blogs` AS `t0` ORDER BY `t0`.`blog_date` DESC
    Possible keys: · Key Used: · Type: ALL · Rows: 2 · Speed: 0.000 ms
    
    No query (0 Queries) are run using:
    $data['results'] = Model_Blog::find()->order_by(array('blog_date' => 'desc'));
    
    Here is my Model_Blog
    class Model_Blog extends Orm\Model {
        protected static $_properties = array('id', 'title', 'post', 'blog_date');
        protected static $_has_many = array('comments');
    }
    
    And here is my Model_Comments
    class Model_Comments extends Orm\Model {
        protected static $_properties = array('id', 'blog_id', 'author', 'comment', 'comment_date');
        protected static $_belongs_to = array('blog');
    }
    
    And my database structure
    --
    -- Table structure for table `blogs`
    --
    
    CREATE TABLE IF NOT EXISTS `blogs` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `title` varchar(255) NOT NULL,
      `post` text NOT NULL,
      `blog_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
    
    -- --------------------------------------------------------
    
    --
    -- Table structure for table `comments`
    --
    
    CREATE TABLE IF NOT EXISTS `comments` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `blog_id` int(11) NOT NULL,
      `author` varchar(255) NOT NULL,
      `comment` text NOT NULL,
      `comment_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
    

    Phil.
  • $data['results'] = Model_Blog::find()->order_by(array('blog_date' => 'desc'));
    
    This won't do a query because you don't tell it to. You create the query using find(), tell it to order desc by blog_date. But you never tell it to execute.
    // find all for your query
    $data['results'] = Model_Blog::find()->order_by(array('blog_date' => 'desc'))->get();
    // get only the first result (or, as you're using "desc" ordering, actually the last)
    $data['results'] = Model_Blog::find()->order_by(array('blog_date' => 'desc'))->get_one();
    
  • Hi, Thanks for the suggestion but I have already tried that and fuel produces the following error: ErrorException [ Error ]: Call to a member function get() on a non-object Phil.
  • Ah, you found a bug - when inputting an array the order_by() method doesn't return its object to allow chaining. I'll fix this in the repo for the next release, for now the following should work:
    $data['results'] = Model_Blog::find()->order_by('blog_date', 'desc')->get();
    
  • OK. Thank you WanWizard and Jelmer for your help. Phil.

Howdy, Stranger!

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

In this Discussion