Akelos Framework v1 forum archive. This forum is no longer maintained. To report bugs please visit https://github.com/akelos/akelos/issues
    • CommentAuthorsuthern
     

    Imagine that I wanted to create another listing which only listed books by a certain author. I'm at a loss as to what to put in the find() function. I've tried using something like what's found in 'show' (@$this->params['id']) instead of the 'all', but to no avail.

    I'd like to call it by doing /booklink/book/listing/author_id/1, or a more pretty way would be /booklink/book/listing/author/frank_smith.

    Is this possible? Does someone have a good resource about the FIND function? Thanks ahead of time!

    • CommentAuthorKaste
     

    I'm at a loss as to what to put in the find() function.

    look here

    a more pretty way would be /booklink/book/listing/author/frank_smith

    thats here

    • CommentAuthorsuthern
     

    Ahhh, thank you so much. Could you help me with one more thing by pointing out why the following attempt still returns ALL the rows from the "Condition" table? $this->condition_pages = $this->pagination_helper->getPaginator($this->Condition, array('items_per_page' => 10)); $this->conditions =& $this->Condition->find('all', array_merge( array('include' => 'part'), array('_conditions.parts_id'=>'1'), $this->pagination_helper->getFindOptions($this->Condition) )); I've also tried it without the array_merge, but that messes up the pagination_helper. Yea, I tried with a foreign key like this array('_parts.id'=>'1') but the results were the same.

    • CommentAuthorsuthern
     

    Even a simple code such as the following returns ALL the rows. I'm stumped. function listing() { $this->condition_pages = $this->pagination_helper->getPaginator($this->Condition, array('items_per_page' => 10)); $this->conditions = $this->Condition->find('all',array('_conditions.part_id'=>'1')); }

    • CommentAuthorKaste
     

    ouch, my fault. I changed the API from find('all',$options); to find('all',$conditions,$options); and I'm so used to it, but its not yet in the trunk. So:

    $this->Condition->find('all',array('_conditions.part_id'=>'1'));

    should be

    $this->Condition->find('all',array(
            'conditions' => array('_conditions.part_id'=>'1')
    ));
    

    I think. Actually, we have inline-docs! Look in AkActiveRecord.php right before the find()-method.

    • CommentAuthorKaste
     

    And btw, do you actually var_dump'ed $this->pagination_helper->getFindOptions($this->Condition)? I don't think you can do an array_merge with your additional conditions.

    • CommentAuthorsuthern
     

    Ah, that AkActiveRecord.php is useful. The examples really help.

    Yes, the $this->pagination_helper line is the first one in the default 'listing' inside ANAME_controller.php. I don't fully understand what it does, as I'm still playing around with everything, trying to make heads or tails out of what does what. It looks like all it does is set the num of rows per page to 10, but I'm not sure, even after looking at the "function getFindOptions(&$object)".

    Thanks for all the help though! I've simplified my example to what you posted, yet it still returns all the rows from the 'conditions' table. (yea, poor table name choice.) Here's the code: function listing() { $this->conditions = $this->Condition->find('all', array('conditions' => array('_conditions.part_id'=>'2'))); } I do like the new way better... I'll keep playing around with it 'till something works.

    • CommentAuthorsuthern
     

    Ok, I've been playing around for a bit, and am really confused. Below are a few examples and their results. It should be fairly obvious that I'm trying to filter the results and still include data from another table.

    This example returns all the rows, with the associated table's data. No filtering: $this->conditions = $this->Condition->find('all', array('include' => array("part")) );

    This example filters the result to just two rows from the 'conditions' table, but does not include any 'parts' data. $this->conditions = $this->Condition->find('all', array('conditions' => "conditions.part_id = 2") );

    This example returns all the rows, just like the first examle, even though the condition array is present: $this->conditions = $this->Condition->find('all', array('conditions' => "conditions.part_id = 2",), array('include' => array("part")));

    When I add them together in the same array, I get an "Notice: Unknown column 'conditions.part_id' in 'where clause' in /home/sambaserve/web/akelos/lib/AkActiveRecord/AkAssociatedActiveRecord.php on line 368" error: $this->conditions = $this->Condition->find('all', array('conditions' => "conditions.part_id = 2", 'include' => array("part")));

    If I modify the last array to look like this: array("part","condition") , to account for the 1st table, I get a very different error: Notice: Undefined property: Condition::$condition in /home/sambaserve/web/akelos/lib/AkActiveRecord/AkAssociatedActiveRecord.php on line 256

    That is why I'm completely confused. The examples inside AkActiveRecord.php clearly show both the 'conditions' and 'include' arguments for the find function, but not in the same example. Is it possible to do both without writing my own SQL SELECT statement? Thanks!

    • CommentAuthorsuthern
     

    I've finally got some code that works! This code does exactly what I want it to do: $_filter = array('conditions' => "part_id = 2"); $_include = array('include' => array('part')); $_options = array_merge($_filter,$_include); $this->conditions = $this->Condition->find('all',$_options);

    Except... There's still no way to filter by a foreign key. If I do "conditions.part_id" in the above example, instead of "part_id", I get the "unknown column 'conditions.part_id" error. And I obviously get a related error if I try "parts.id". So, why can't I use "tablename.fieldname" to refer to a field while doing 'include'?

    == Summary ==
    "tablename.fieldname" works fine without an include array.
    "fieldname" works with the include array, but is useless. If I'm including more than one table, you can bet that I'm gunna be doing some sort of filter based on the joined table. The only way I know of addressing fields in a multiple table query is "tablename.fieldname".

    Has anyone else run into this?

    • CommentAuthorKaste
     

    That is why I'm completely confused.

    lol. but thats not really your fault. ;-)

    maybe when you put a $this->conditions->dbug() before your finder it'll will make a gotcha. see, include does a join of course, and we alias the join-table, so "tablename.fieldname" won't work anymore.

    The alias name should be _associationname:

    parts.id           => _parts.id
    

    And yes, I don't think this is very intuitive. Maybe we will change this until v0.9.

    • CommentAuthorsuthern
     

    Ah, that dbug is very useful! I was wondering how I could see the SQL to troubleshoot it. Thanks. Yup, this code does exactly what I set out to do. function listing() { $this->condition_pages = $this->pagination_helper->getPaginator($this->Condition, array('items_per_page' => 10)); if(!empty($this->params['id'])) { $_filter = array('conditions' => '_part.id = '.@$this->params['id']); } else { $_filter = array(); }; $_include = array('include' => array('part')); $options = array_merge($_filter,$_include,$this->pagination_helper->getFindOptions($this->Condition)); $this->conditions = $this->Condition->find('all',$options); } Thanks for all the help Kaste! I think your contributions are invaluable to this community.

    • CommentAuthorThijs
     

    While building on this example I noticed the condition in the search isn't passed on to the pagination helper. So the result would be as many pagelinks as in a find all.

    I think it should be something like this:

    function listing()
    {       
        if(!empty($this->params['id'])) { 
           $_filter = array('conditions' => '_part.id = '.@$this->params['id']);
           $_filter_pagination = array('items_per_page' => 10, 'count_conditions' => '_part.id = '.@$this->params['id']);
        }else{ 
           $_filter = array();
           $_filter_pagination = array();
        }
    
        $_include = array('include' => array('part'));
    
        $this->condition_pages = $this->pagination_helper->getPaginator($this->Condition,$_filter_pagination,$_include);
    
        $options = array_merge($_filter,$_include,$this->pagination_helper->getFindOptions($this->Condition));
        $this->conditions = $this->Condition->find('all',$options);
    }
    

    'count_conditions' in the getPaginator method definitely works this way, but I'm not sure that the 'include' => array('part') will work the same for the paginator as it does for the Find. (in my search I didn't need an 'include', so I have not tried it)

    • CommentAuthorjujulka
     
    it doens't work with relations many-2-many:(
    need use "count_joins"

    $this->place_pages = $this->pagination_helper->getPaginator($this->Place,
    array('items_per_page' => self::ITEM_PER_PAGE,
    'count_joins' => 'LEFT JOIN places_types ON(places_types.place_id = places.id) INNER JOIN types ON(types.id=places_types.type_id)',
    'count_conditions' => "types.id = $type_id"));