Gegeben ein array von ActiveRecord-Objekten, kann ich ganz einfach sammeln Sie Ihre Beziehungen durch einen Aufruf der Methode?
-
03-07-2019 - |
Frage
Sagen wir, ich habe den folgenden code:
@sites = Site.find(session[:sites]) # will be an array of Site ids
@languages = Language.for_sites(@sites)
for_sites ist ein named_scope in der Sprache Modell liefert, dass die Sprachen, die in Zusammenhang mit diesen Websites, und Sprachen mit Websites verbunden mit has_many durch.Das Ziel ist für @Sprachen haben eine unterschiedliche Anordnung der Sprachen im Zusammenhang mit den Websites.
Anstelle von aufrufen der Sprache-Objekt auf der zweiten Linie, würde ich am Liebsten sagen
@sites.languages
und die gleiche Liste wieder zu mir.Gibt es eine Möglichkeit zu tun, die sauber in Rails 2.1 (oder edge)?Ich weiß, Verbände und scopes können verlängern die array-Objekt, Attribute, aber es sei denn, mir fehlt etwas das nicht gelten hier.Alle plugins, die dies tun, würde willkommen sein, es muss nicht sein Kern.
Lösung
Sie könnten verlängern die array zurückgegeben Website.finden.
class Site
def find(*args)
result = super
result.extend LanguageAggregator if Array === result
result
end
end
module LanguageAggregator
def languages
Language.find(:all, :conditions => [ 'id in (?)', self.collect { |site| site.id } ])
end
end
Andere Tipps
Warum nicht named_scopes für beide?
class Site
named_scope :sites, lambda{|ids| :conditions => "id in (#{ids.join(',')})"}
named_scope :languages, :include => :languages ... (whatever your named scope does)
end
Anruf:
Site.sites(session[:sites]).languages
oder, wenn Sie wollen die Sprache der Objekte zurück
Site.sites(session[:sites]).languages.collect{|site| site.languages}.flatten
Sie können auch direkt auf der Language-Objekt.Ich bin mit :joins, weil Rails 2.1 spaltet und :in zwei Abfragen, die bedeutet wir können nicht Websites in der :Bedingungen
class Language
named_scope :for_sites, lambda{|site_ids| :joins => 'inner join sites on languages.site_id = sites.id' :conditions => "sites.id in (#{site_ids.join(',')})"}
end
Anruf:
Language.for_sites(session[:sites])
In beiden Beispielen habe ich angenommen, dass die Sitzung[:Seiten] ist vollständig gesteuert durch Sie, und nicht Thema zu SQL-injection.Wenn nicht, stellen Sie sicher, dass Sie deal mit die Reinigung der ID ' s
Die Instanz-variable @Standorten ist ein Array-Objekt und nicht vor Ort, so dass ich glaube nicht, dass named_scope verwendet werden kann.Können Sie öffnen Array-Klasse um diesen Effekt zu erzielen, obwohl (Huch)
class Array
def languages
...
end
end
Wenn Sie einen has_many
oder has_and_belongs_to_many
die Verknüpfung von Sprachen zu Websites, dann könnten Sie ein beinhalten und so etwas wie dies tun:
Site.find( :all, :conditions =>{:id => session[:sites]}, :include => :languages )
Sie können einen benannten Bereich zu tun,: id => session[:Seiten] Sache, z.B.:
class Site
named_scope :for_ids, lambda{ |x| {:conditions => {:id => x }
end
und dann tun,
Site.for_ids(session[:sites]).find(:all, :include => :languages)
Hoffe, das gibt Ihnen einige Ideen,