Frage

Okay, ich bin auf diese gründlich stapfte. Ich versuche, ein Menü der veröffentlichten Webseiten nach Kategorie zu bauen.

Category.rb:

belongs_to :parent, :class_name => "Category", :foreign_key => "parent_id"
has_many   :children, :class_name => "Category", :foreign_key => "parent_id"
has_many :pages, :documents, :galleries

Page.rb

belongs_to :category

Die Seite Modell auch hat: is_published, so dass ich zum Filter bin versucht auch, dass auf. Ich bin nur ungern meine schwache Abfrage versucht zu schreiben, aber keine andere Lösung sehen als viel intelligentere Menschen zu bitten:

(Selbst ist @current_website)

self.categories.includes(:children, :pages).where('pages.is_published = 1')

Dies gibt vor allem, was ich brauche, aber nicht übergeordnete Kategorien ohne veröffentlichten Seiten. Zum Beispiel, es funktioniert großartig, wenn ich:

Parent Category
- Published Page
- Child Category
-- Published Page

Wenn es nicht ist, wenn ich keine veröffentlichten Seiten in der Mutter haben, wie folgt aus:

Parent Category
- Child Category
-- Published Page
- Child Category
-- Published Page

Vielen Dank im Voraus für jede Hilfe zu diesem Thema. Ich versuche, so viel zu lernen, wie ich kann über Abfragen, aber ich bin gegen die Wand zu diesem Thema.

UPDATE: Implementieren KandadaBoggu Vorschlag viel bessere Ergebnisse erbracht hat, wurde dieser zu Category.rb hinzugefügt

  has_many :published_pages, :class_name => "Page",
                             :conditions => {:is_published => true}

Wenn Sie jedoch die folgenden:

self.categories.where(:parent_id => nil).includes({:children => :published_pages},
                                                   :published_pages)

Ich bekomme die Ergebnisse, die ich brauche, aber ich auch leer Eltern Kategorien (keinen published_pages bekommen, keine Kinder Kategorien mit veröffentlichten Seiten Eines Beispiel:.

- Parent Category
-- Published Page
- Parent Category
-- NOTHING

Meine temporäre Lösung war beigefügtem die Abfrage mit:

reject{|category| category.pages.empty? && category.children.empty?}

Nochmals vielen Dank für Ihre Hilfe.

War es hilfreich?

Lösung

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)
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top