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:[email protected]
http://www.schuerig.de/michael/
_______________________________________________
rubyonrails-ug mailing list
[email protected]
http://mailman.headflash.com/listinfo/rubyonrails-ug