du kannst ein ARec objekt nach seinem arel_table fragen und dem arel methoden übergeben
Beste Grüße Thomas von Deyen magic labs* (von unterwegs gesendet) Am 04.02.2012 um 20:14 schrieb Michael Schuerig <michael.li...@schuerig.de>: > > Ich arbeite zur Zeit daran, eine alte (Rails 2.1) Anwendung auf Rails > 3.2 umzustellen. Dabei möchte ich auch möglichst viel handgeschriebenes > SQL durch schönere Ausdrucksmittel ersetzen. > > Noch recht harmlose Fälle sehen so aus > > class Document < ActiveRecord::Base > scope :newest, > joins( > 'LEFT OUTER JOIN documents newer > ON newer.doc_code = documents.doc_code > AND documents.version < newer.version' > ). > where('newer.doc_code IS NULL'). > readonly(false) > end > > Hier habe ich readonly(false) schon hinzufügen müssen, weil ARec > andernfalls die zurückgegebenen Objekte als readonly markiert. Das > passiert gerade weil der Join nur als "opaker" String angegeben ist. > > Ein vielleicht naheliegender Ausweg sieht so aus > > class Document < ActiveRecord::Base > has_many :newer_versions, > :class_name => 'Document', > :foreign_key => :doc_code, > :primary_key => :doc_code, > :conditions => > 'documents.version < newer_versions_documents.version' > > scope :newest, > includes(:newer_versions). > where(:newer_versions => { :doc_code => nil }) > end > > Hier generiert ARec ein SELECT-Statement, das auch die (leeren) Spalten > von newer_versions_documents zurückliefert. Nicht wirklich schlimm, aber > unschön. Vor allem aber funktioniert dieser Trick zwar in diesem Fall, > aber etwas Subqueries, die ich auch habe, lassen sich damit nicht > ausdrücken. > > Aber war da nicht was? ActiveRecord 3.x basiert doch auf ARel und man > kann die irgendwie gemeinsam nutzen. Wenn es mir denn gelingen würde. > Ich finde einfach keine Beispiele, die zeigen, wie es gehen könnte. > > Ich kann den gewünschten LEFT OUTER JOIN mit ARel-Mitteln so ausdrücken: > > docs = Document.arel_table > newer = docs.alias > loj = docs.join(newer, Arel::Nodes::OuterJoin). > on(newer[:doc_code].eq(docs[:doc_code]). > and(docs[:version].lt(newer[:version]))). > where(newer[:doc_code].eq(nil)) > > Aber wie baue ich das in einen Scope ein? Ich brauche etwas, was auch > mit anderen Scopes, die für Document definiert sind, verkettet werden > kann. > > Weiß jemand, wie es geht? > > Michael > > -- > Michael Schuerig > mailto:mich...@schuerig.de > http://www.schuerig.de/michael/ > _______________________________________________ > rubyonrails-ug mailing list > rubyonrails-ug@headflash.com > http://mailman.headflash.com/listinfo/rubyonrails-ug _______________________________________________ rubyonrails-ug mailing list rubyonrails-ug@headflash.com http://mailman.headflash.com/listinfo/rubyonrails-ug