Gegeben ein array von ActiveRecord-Objekten, kann ich ganz einfach sammeln Sie Ihre Beziehungen durch einen Aufruf der Methode?

StackOverflow https://stackoverflow.com/questions/220126

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.

War es hilfreich?

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,

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top