tags:

views:

69

answers:

2

I am building a book review application.

In the Review model, I have book_id and several fields like author_rating and/or scary_rating.

In the Book model, I have a search() function that I'd like to use to search for books with certain characteristics, like an author_rating of above 5, for example.

What is the best way to accomplish this? I know these are probably wrong, but I could add the attributes (author_rating, scary_rating, etc) into the book model and update them (average them in) each time a review is submitted; or, I could run a cron task that updates those fields every so often.

But is there a better way where I could query both the Book and Review models to come up with Books and meet certain criteria defined by looking at the Reviews database?

Does that make sense?

+1  A: 
you could use union, to combine two queries!!!

query 1......

union

query 2.....

order by ratings LIMIT 1

in this kind of format, if you want real life example, then im willing to give you one,

SELECT
               u.username, u.picture,m.id, m.user_note, m.reply_id, m.reply_name, m.dt
              FROM
                relationships r,
                notes m,
                user u
              WHERE
                m.user_id = r.leader
              AND
                r.leader = u.user_id
              AND
                r.listener = '$user_id'
             UNION
               select username, picture,id, user_note, reply_id, reply_name, dt
               from user u, notes b
               where u.user_id = b.user_id
               and
               b.user_id ='$user_id'
               ORDER BY dt DESC LIMIT 10";
getaway
so basically you can have this this query built into one model!!! so your dealing with database side rather than the application, if you get what i mean!!1 :))
getaway
Thank you very much for the help! I will search CakePHP documentation to see if this is supported by any helpers.
Justin
pleasure, anytime! :))
getaway
I don't think this accomplishes what the question was asking.
handsofaten
why is that? :))
getaway
Unless I misunderstand the question, I think Justin wants to average the review ratings, and I don't see anything here that would do that. See my answer.
handsofaten
i dnt know lol im so confused, i just tried to help!! sorry for misunderstanding
getaway
This was applicable to the way I was originally trying to do it, so it was helpful in that aspect, but I ended up switching to the way described in my comment below. Thanks for the help anyway getaway and for your help as well handsofaten!
Justin
A: 

It sounds like you have a bunch of reviews and you want to average them on the fly when someone searches, is this correct? If so, I think it would probably work better to save the averaged ratings as fields in the Book model.

The reason I say this is that it is likely your app will be doing more searching than saving reviews, and it's probably more important to have searches returned quickly than reviews saved quickly.

However, if you want to calculate these averages on the fly, you can use MySQL's AVG() function. Check this SO post for an example that I think is pretty close to your situation:

http://stackoverflow.com/questions/1627567/mysql-can-i-combine-these-2-sql-statements-combine-join-and-avg

Also, this is a situation where I'd probably just write the SQL and stick it into a query(), rather than trying to wrestle with Cake's ORM syntax:

http://book.cakephp.org/view/456/query

handsofaten
Yes, I ended up coming to the same conclusion with the averaging fields in the Book model. I was just looking into how to do this using CakePHP's ORM, but it's looking needlessly complex, so I think I'll take your advice and put it into a query. The problem is that these aren't simple averages... they need to take into account the number of previous ratings in order to not average in at "50%", so I setup counterCache and used that to populate a review_count field in the Book model that I'm going to use to calculate.
Justin
Sounds like a good approach... good luck!
handsofaten