Nested resources vertauscht ID's


#1

Hallo,

ich habe ein Problem mit nested resources.

Ich habe in der routes.rb folgenden Eintrag:

map.resources :projects do |project|
project.resources :iterations do |iteration|
iteration.resources :tasks
end
end

wenn ich folgenden Link ausgeben will über:

<%= link_to ‘Show’, project_iteration_task_path(task.iteration.project,
task) %>

bekomme ich folgenden Link angezeigt:

http://localhost:3000/projects/2/iterations/117/tasks/32

Das Problem ist jedoch, dass die die IDs von iterations und task
vertauscht werden. Also eigentlich ist die iteration_id = 32 und die
task_id = 117.

Kennt jemand eine Lösung für mein Problem bzw. was mache ich falsch?

Vielen Dank im voraus!


#2

Hallo Herman,

wenn du im Projektverzeichnis “rake routes” aufrufst, werden die die
Routen angezeigt.

Dort sieht du dann auch:

project_iteration_task
GET /projects/:project_id/iterations/:iteration_id/tasks/:id
{:controller=>“tasks”, :action=>“show”}

Die Methode erwartet drei Parameter: project_id, iteration_id und id
für Task.
Der Aufruf lauter daher:

project_iteration_task(task.iteration.project, task.iteration, task)

oder

project_iteration_task(:project_id =>
task.iteration.project, :iteration_id => task.iteration, :id => task)

GrüßeThomas

Am 01.11.2008 um 16:23 schrieb Herman Müller:

end
Das Problem ist jedoch, dass die die IDs von iterations und task
removed_email_address@domain.invalid
http://mailman.headflash.com/mailman/listinfo/rubyonrails-ug


Thomas B.
b-simple.de - Ruby on Rails - Entwicklung & Training
Bei den Mühren 70, 20457 Hamburg
+49 (173) 2391143 - thomas.baustert(at)b-simple.de
Umsatzsteuer-Identifikationsnummer: DE814405137


#3

Hallo Thomas,

vielen Dank!!

Hat einwandfrei funktioniert.

Aber irgendwie kann ich mich mit den langen URLs nicht anfreunden, ist
erheblich mehr Arbeit als mit den kurzen URLs, über z.B.
map.resources :projects, :has_many => [ :iterations]
map.resources :iterations, :has_many => [ :tasks]

Ergebnis --> http://localhost:3000/iterations/36/tasks/140

Diese URL ist zwar nicht so schön erklärend wie,

http://localhost:3000/projects/2/iterations/36/tasks/140

welche jedoch einen erheblich höheren Code-Aufwand bedeutet.

Hast Du vielleicht noch irgendwelche Tipps für Applicationen mit tiefer
verschachtelten nested resources?

Wünsche Dir ein schönes Wochenende!

Gruß

Dietmar


#4

Hallo Dietmar,

ah, ich liebe diesen nested-resources-thread, der alle paar Wochen mal
wieder auftaucht und dann wieder einschläft, ohne dass man wirklich zu
einer Lösung gekommen wäre :slight_smile:

Wir benutzen hier noch immer, wirklich wirklich tief geschachtelte
ressourcen (project -> container -> quiz -> question -> answer), vor
allem, weil ich das damals für die “natürlichste” Art gehalten habe,
das abzubilden, weil das Business-Model genau so ist. Die Lehrmeinung
ist: Don’t use deeply nested routes. Eine wirkliche, schlagende
Argumenation dagegen habe ich bislang aber auch noch nicht gehört -
hier sind die die Vor- Nachteile, die wir hier praktisch erfahren:

Contra:

  • die routes werden deutlich komplizierter/länger.
  • eine Hierarchie-Änderung ist beinah immer tödlich, weil diese
    Hierarchie in vielen verschiedenen Controllern/views benutzt wird.
  • not DRY: die Modelle sind ja schon genestet, die iteration kennt ihr
    Projekt, der task seine iteration, damit hat projects/2/iterations/36/
    tasks/140 dieselben Informationen wie /tasks/140

pro:

  • ein einheitlicher Weg, den Kontext für einen Controller wieder
    herzustellen: Wenn man einen Task editiert, dann braucht man im View
    in der Regel auch immer Informationen über project und iteration. Wir
    machen das über einen before_filter, der davon ausgeht, dass in der
    route immer project und iteration drin sind. Hat man das nicht, dann
    muß man entweder im View oder im Controller den Pfad bis nach oben
    wiede ablaufen, bis man bei den Kontext-Objekten angekommen ist - und
    dieser Pfad ist halt nicht immer derselbe.
  • für den edit/view sind die Informationen redundant (/tasks/140),
    aber für den create nicht: /tasks/140, da braucht man die iteration im
    Pfad. Aber man muss sich halt für eine Variante der route entscheiden
    und dann ist die genestete in der Regel die “natürlichere” (die, die
    besser zum Modell passt).

In der Praxis überwiegen die Contras: Das “natürlichere” Nesting ist
besser, um zu verstehen, wie die Controller funktionieren müssen, aber
irgendwann macht einen das wahnsinnig, diese ganzen Parameter überall
mitschleppen zu müssen. Man kommt da zwar mit helpern für die Routes
und Konventionen drum herum, aber schön ist das nicht. Wir sind
inzwischen dazu übergegangen: So tief wie nötig und so flach wie
möglich schachteln.

Wirklich Abhilfe kommt da aber glaub ich erst mit 2.2:
http://ryandaigle.com/articles/2008/9/7/what-s-new-in-edge-rails-shallow-routes

Damit kann man das Beste aus beiden Welten haben: Lange, natürliche
Pfade für’s Create, und kurze für’s edit, wenn man bereits eine id
hat, the holy grail of nesting…

Viele
GrüßeStefan

Am 01.11.2008 um 19:57 schrieb Herman Müller:

verschachtelten nested resources?
removed_email_address@domain.invalid
http://mailman.headflash.com/mailman/listinfo/rubyonrails-ug


stefan frank
vierundsechzig.de
software&service
weberstr. 10
69120 heidelberg
tel. +49 (0) 6221 7277049
mobil +40 (0) 173 2383390
mail removed_email_address@domain.invalid
www.vierundsechzig.de