2015-10-16 8 views
6

Ich benutze Rails 4.2. Ich habe 3 Tabellen wie folgt aus:Rails: `beinhaltet` eine `has_many` Relation mit` limit`

class Collection < ActiveRecord::Base 
    has_many :shares 
    has_many :images, through: :shares 
    has_many :latest_images, -> { order(created_at: :desc).limit(10) }, class_name: 'Image', through: :shares, source: :image 
end 

class Share < ActiveRecord::Base 
    belongs_to :image 
    belongs_to :collection 
end 

class Image < ActiveRecord::Base 
    has_many :shares 
    has_many :collections, through: :shares 
end 

Mein Ziel ist es, einige Sammlungen und Vorspannung der ersten 10 neuesten Karten von jeder Kollektion mit der latest_images Beziehung zu wählen.

Wenn ich einfach:

collections = Collection.where(some_condition).includes(:latest_images) 

Das Problem ist latest_images alle Karten enthalten nicht nur die letzten 10 (auch wenn es ein limit(10))

collections.first.latest_images.count # => more than 10!!! 

Stattdessen, wenn ich das hinzufügen limit(10) nach dem Laden der Sammlungen, werde ich ein N + 1 Abfrageproblem haben:

Irgendeine Lösung?

Antwort

3

Es gibt eine Notiz in den associations documentation unter „Eager Laden von Verbänden“ versteckt:

Wenn Sie eifrig Last eine Verbindung mit einer bestimmten: Limit-Option, wird sie ignoriert, Rückkehr all zugehörige Objekte .

Also verhält es sich wie dokumentiert, obwohl das nicht das intuitive Verhalten ist.

Die Arbeit ist um nicht eifrig laden die begrenzte zugeordnet und separat danach zugreifen. Wie Sie bemerken, ist das nicht ideal, aber es ist fast sicher vorzuziehen, alle zugehörigen Objekte ohne Begrenzung zu laden.

+0

Also gibt es keine Möglichkeit, diese Daten zu laden, ohne alles zu laden und N + 1 Abfrage zu vermeiden? – ProGM

+2

Nein, ich benutze die Arel-Schnittstelle nicht. Du könntest deinen eigenen Code schreiben, um es zu tun, aber du wirst es leider nicht umsonst bekommen. – Shadwell

Verwandte Themen