On Wed, Dec 8, 2010 at 12:26 PM, FahDoos <[email protected]> wrote:
> Tried searching for answers but can't find any good.
>
> To keep it basic, I have a conversations model, which has a one to
> many relationship with messages. In the conversations view i'd like to
> list each conversation sorted by the date of the most recent message,
> and display the body of that message. High level help would be fine,
> and code examples a bonus.
>
> What i've tried so far:
>
> 1) creating an hasOne relationship to the messages model. This just
> results in the conversation getting duplicated for every related
> message it has.
>
> 2) created an additional hasMany relationship to messages model with a
> limit of 1 sorted by date desc. This sorta works, but the single
> related message ends up in an array with one index of 0.
>
> I know there has to be a more graceful solution for this. I'm an
> experienced php programmer who's new to cake... so far really loving
> it, but just getting bit in the a$$ with how to best leverage cake in
> some instances.


The best solution I can think of would be to use both
ContainableBehavior[1] and counterCache[2]. The first is to make it
simple to order & limit the associated Message. The latter, to order
the Conversations (I think--I'll explain below).

First, the code ...

Message model:

public $belongsTo = array(
        'Conversation' => array(
                'counterCache' => 'messages_count'
        )
);

Conversation model:
public $hasMany = array(
        'Message'
);


ConversationsController:

public $paginate = array(
        'Conversation' => array(
                'fields' => array('Conversation.*'),
                'order => array(
                        'Conversation.modified' => 'DESC'
                ),
                'limit' => <number conversations per page>,
                'contain' => array(
                        'Message' => array(
                                'order' => array(
                                        'Message.created' => 'DESC'
                                ),
                                'limit' => 1
                        )
                )
        )
);

(You could also create an entry here for Message, so that you could
paginate all Messages for a particular Conversation in the view
action.)

Containable allows us to both order & limit the associated model
records, so order on the created column and limit to a single record.
Normal stuff. That's step 1.

Ordering the Conversations, however, is done on the modified column.
This is where I'm straying into untested waters, but I'm pretty sure
it should work. We use counterCache by specifying it--in the model
whose records we want to count--as a key in the association array for
the model whose table will hold the count. So, here it's included in
Message's $belongsTo entry for Conversation. Then, we need a
messages_count column in the conversations table.

Now, you didn't ask to count messages per conversation but this is
where the trick lies (I think). And, you get a handy count of Messages
per Conversation as a bonus.

Cake will automatically set the values of DATETIME columns named
created and modified. I'm (mostly) sure that the modified column will
be updated when the counterCache column--messages_count--is. So, this
could be used to paginate Conversations by their most recent Message.
I think. I can certainly see why the Cake devs might have preferred to
inhibit updating the modified column when updating a counterCache
column because this would be undesirable to some people. Anyways, I'd
check the code myself and/or build a test as I'm really curious now,
but I'd better quit procrastinating and get backto work.

[1] http://book.cakephp.org/view/1323/Containable
[2] http://book.cakephp.org/view/1033/counterCache-Cache-your-count

Check out the new CakePHP Questions site http://cakeqs.org and help others with 
their CakePHP related questions.

You received this message because you are subscribed to the Google Groups 
"CakePHP" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected] For more options, visit this group at 
http://groups.google.com/group/cake-php?hl=en

Reply via email to