Rails 3 - Eager loading with conditions

后端 未结 1 1476
长情又很酷
长情又很酷 2020-12-03 15:16

Okay, I\'m thoroughly stumped on this one. I\'m trying to build a menu of published web pages organized by category.

Category.rb:

belongs_to :parent,         


        
相关标签:
1条回答
  • 2020-12-03 15:54

    Add a new association called published_pages (apart from your current associations)

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

    Now you can get all the categories as follows:

    self.categories.includes(:children, :published_pages)
    

    If you are interested in learning why your approach didnt work, read the Rails documentation (scroll 10-15 lines after the Eager loading of associations section). I have included the relevant snippet below:

    For example

    Post.includes([:author, :comments]).where(['comments.approved = ?', true]).all
    

    This will result in a single SQL query with joins along the lines of:

    LEFT OUTER JOIN comments ON comments.post_id = posts.id and 
    LEFT OUTER JOIN authors  ON authors.id = posts.author_id. 
    

    Note that using conditions like this can have unintended consequences. In the above example posts with notion approved comments are not returned at all, because the conditions apply to the SQL statement as a whole and not just to the association. You must disambiguate column references for this fallback to happen, for example :order => "author.name DESC" will work but :order => "name DESC" will not.

    To eager load filtered rows of an association, use an association with conditions:

    class Post < ActiveRecord::Base
      has_many :approved_comments, :class_name => 'Comment', 
                 :conditions => ['approved = ?', true]
    end
    
    Post.find(:all, :include => :approved_comments)
    
    0 讨论(0)
提交回复
热议问题