Books belongs_to authors. How to find only author with books

Hello

I have a table called Books
And a table called Authors

Books belong_to authors

How can I find only authors that have books?

Thanks

Fernando B. wrote:

Hello

I have a table called Books
And a table called Authors

Books belong_to authors

How can I find only authors that have books?

Thanks

I think an author can write many books
so that you can put has_many :books in Author ActiveRecord

so that you can find books easily

@author = Author.find(:first)

@books = @author.books

Reinhart
http://teapoci.blogspot.com

I thought I’d point out too that one book can have multiple authors, so
you
might need something like

Book
id
name

Writings
book_id
author_id

Author
id
name

and use something like

Books has_many :authors, :through => :writings
Writings belongs_to :book, belongs_to :author
Author has_many :books, :through => :writings

To get that many to many relationship working.

As for your question, and using the above, now all you need to do is
construct a find query to get authors if COUNT(*) FROM writings WHERE
author_id = [id here] and check its size is > 0

That would be my solution anyway. A more exp. rails dev might have a
faster
option.

Regards
Kieran

On Mon, Jun 2, 2008 at 9:08 AM, Rails T. <

This is not optimal code, but you can make a method in Author:

def self.find_all_with_books
authors = []
for author in self.find(:all)
authors << author if author.books.count > 0
end
authors
end

If you’re using Rails 2.1 you can check out named_scope. Not familiar
with it yet, but it goes something like this

class Author < …
has_many :books
named_scope :published, :include => :books, :conditions =>
[“books.count > 0”]

I’m pretty sure the code won’t work. Watch this to be more familiar
with it though #108 named_scope - RailsCasts

On Mon, Jun 2, 2008 at 4:15 AM, Fernando B.
[email protected] wrote:

Thanks

Posted via http://www.ruby-forum.com/.


Ramon T.

On Mon, Jun 2, 2008 at 8:27 AM, sullivan.t [email protected] wrote:

I like that, though what about finding the db records with sql and a
standard table join?

I suppose it’d be the same in terms of cpu cycles, etc.

No it wouldn’t, doing it in SQL would result in one query and less
cycles.

Something like:

Author.find(:all, :joins => :books)

Should do the trick, this should do a query with an inner equijoin on
Authors and Books, so Authors without books would not be returned.

Note that I haven’t actually tested this code.


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

I like that, though what about finding the db records with sql and a
standard table join?

I suppose it’d be the same in terms of cpu cycles, etc.

On Jun 1, 10:34 pm, “Ramon Miguel M. Tayag” [email protected]

On 2 Jun 2008, at 13:50, Rick DeNatale wrote:

Something like:

Author.find(:all, :joins => :books)

Should do the trick, this should do a query with an inner equijoin
on Authors and Books, so Authors without books would not be returned.

Note that I haven’t actually tested this code.

There’s always the cheat’s version: have a counter_cache on books.

Fred

Hey everyone! Well what do you know? I had to do this today, right
after I emailed.

If you’re going to use named_scope, you have to setup a counter cache.

then, in Author:

named_scope :published, :conditions => [“books_count > 0”]

if not named_scope, try:

Author.find(:all, :conditions => [“books_count > 0”])

Either way, counter_cache would be a good thing to setup since doing
these kinds of finds will be a lot less CPU intensive.


Ramon T.