Frage Rails has_many, finde nur diejenigen mit Kindern


Meine Tabelle "products" has_many: registered_products.

Ich möchte etwas wie

products.find(:has_registered_products) 

Hier werden nur die Produkte zurückgegeben, die ebenfalls einen Eintrag in der Tabelle registred_products enthalten. Wie könnte ich das erreichen?


5
2018-03-24 22:45


Ursprung


Antworten:


Solange Sie einen Fremdschlüssel für das Produkt in der Tabelle registred_products haben, können Sie Folgendes tun:

has_many :registered_products
named_scope :with_registered_products, :joins => :registered_products

# if you're using rails 3
scope :with_registered_products, joins(:registered_products)

und das wird nur Produkte zurückgeben, die mindestens ein zugeordnetes registriertes Produkt haben.


10
2018-03-24 22:49



Dies wird die Duplizierung behandeln.

Product.joins(:registered_products).uniq

3
2018-03-04 13:20



Wie Jakob hervorhebt, müssen Sie sicherstellen, dass mehrere übergeordnete Objekte nicht zurückgegeben werden, wenn mehrere untergeordnete Datensätze vorhanden sind.

Die Verwendung von "Select Diskrete" funktioniert, aber die Select-Anweisung könnte stören, wenn dieser Bereich mit anderen Bereichen kombiniert wird.

Eine weitere Option besteht darin, sicherzustellen, dass Sie einer untergeordneten Tabelle mit nur eindeutigen Datensätzen beitreten. Sie können dies tun, indem Sie Ihren Join wie folgt verfassen

class Product < ActiveRecord::Base
 has_many registered_products

 scope :with_registered_products, joins('join (select distinct product_id from registered_products) rp123456 on rp123456.product_id = products.id')
end

1
2018-05-23 19:18



class Product
  has_many :registered_products
end

Liste der Produkte (mit mindestens einem registrierten Produkt) - Eifrig geladene registrierte Produkte

Product.all(:include => :registered_products, 
  :conditions => "registered_products.id IS NULL")

Liste der Produkte (mit mindestens einem registrierten Produkt) - Ohne eifriges Laden

Product.all(:joins => :registered_products)

0
2018-03-24 23:03



Sie könnten counter_cache (http://railscasts.com/episodes/23-counter-cache-column) verwenden. Es sollte schneller sein, als tatsächlich die Verbindung zu machen, nur um herauszufinden, ob es Kinder gibt.


0
2018-03-24 23:50