The only way I can think of to do this is using multiple joins on the join table, one for each tag that you want to AND together. This doesn't scale very well, but works fine for two. The query you want, assuming your join model is called taggings with a foreign key book_id:
SELECT DISTINCT books.* FROM books
INNER JOIN taggings t1 ON t1.book_id = book.id
INNER JOIN taggings t2 ON t2.book_id = book.id
WHERE t1.id = (SELECT id FROM tags WHERE name = 'A')
AND t2.id = (SELECT id FROM tags WHERE name = 'B')
You can try to use this with the find method, good luck :) Probably easier to just use find_by_sql, like this:
Book.find_by_sql(["SELECT DISTINCT books.* FROM books
INNER JOIN taggings t1 ON t1.book_id = book.id
INNER JOIN taggings t2 ON t2.book_id = book.id
WHERE t1.id = (SELECT id FROM tags WHERE name = ?)
AND t2.id = (SELECT id FROM tags WHERE name = ?)", 'A', 'B')
This assumes that tags.name is unique.