0

I have the following query:

@books = Books.includes(:author, :pages)
              .find(:all,
                    :order => 'created_at DESC')

Let's assume my "Pages" table has fields "words, pictures". For blank pages, field "words" is NULL. There are many "Pages" records per book.

The problem with the above query, is that it retrieves ALL the pages for each book. I would like to retrieve only 1 page record for example with the condition "NOT NULL" on the "words" field. However, I don't want to exclude from the query results the Books that do not match the pages query (I have 10 books in my table and I want 10 books to be retrieved. The book.page association should be "nil" for the books where the condition does not match.)

I hope this makes sense.

fnllc
  • 3,047
  • 4
  • 25
  • 42

2 Answers2

0

Check this SO question: Rails 3 - Eager loading with conditions

It looks like what you want

class Category

  has_many   :children,        :class_name => "Category", 
               :foreign_key => "parent_id"
  has_many   :published_pages, :class_name => "Page", 
               :conditions  => { :is_published => true }

end
Community
  • 1
  • 1
Rodrigo Zurek
  • 4,555
  • 7
  • 33
  • 45
0

If you only want a single blank page to be returned then you could add an association:

has_one :first_blank_page, -> {merge(Page.blanks).limit(1)}, :class_name => "Page"

... where in page.rb ...

def blanks
  where(:words => nil)
end

Then you can:

@books = Books.includes(:author, :first_blank_page).order('created_at desc')

... and subsequently reading first_blank_page would be very efficient.

The limit will not be used if you eager load, though, as the SQL syntax for that sort of this would be very complex to execute as one query, so you'd want to consider whether you want to eager load all of the pages per book and then just use one per book. It's a tricky trade-off.

David Aldridge
  • 51,479
  • 8
  • 68
  • 96