2016-09-19 2 views
0

Etwas Neues zu Schienen und versuchen, einige Antworten zu Fragen zu finden, die ich mit keinem wirklichen Glück mit der Rails-Dokumentation oder auf den Schienen geführt habe, oder Schienen Tutorials.Rails 5: Refactoring - Eine-zu-viele-Beziehung (Tests und Ansichten)

Mein Ziel ist es zu begreifen, wie Schienen mit Dingen umgehen und anderen Entwicklern den Einstieg in das Projekt zu erleichtern.

Frage 1: Refactoring Frage

Rails Praxis in Refactoring. Ich bin mir nicht sicher, ob dies in das Modell oder den Controller gehen sollte und möchte wirklich nur wissen, welche Elemente in den Controller gehen sollten, im Vergleich zu dem, was in dem Modell gehen soll.

Erste Iteration:

<% @departments.each do |department| %> 
     <tr> 
     <td><%= department.name %></td> 
     <td><%= department.description %></td> 
     <td> 
      <%= library = Library.find_by(id: department.library_id).name %> 
     </td> 
     <td><%= link_to 'Show', department %></td> 
     <td><%= link_to 'Edit', edit_department_path(department) %></td> 
     <td><%= link_to 'Destroy', department, method: :delete, data: { confirm: 'Are you sure?' } %></td> 
     </tr> 
    <% end %> 

Das schien mir falsch und schien so aus, dass ein Teil als Back-End-Logik genommen werden sollte.

Zweite Iteration:

Modell

class Department < ApplicationRecord 
    belongs_to :library 

    def get_library_name(lib_id) 
    library = Library.find_by(id: lib_id) 
    return library.name 
    end 
end 

Ansicht

<% @departments.each do |department| %> 
     <tr> 
     <td><%= department.name %></td> 
     <td><%= department.description %></td> 
     <td> 
      <%= department.get_library_name(department.library_id) %> 
     </td> 
     <td><%= link_to 'Show', department %></td> 
     <td><%= link_to 'Edit', edit_department_path(department) %></td> 
     <td><%= link_to 'Destroy', department, method: :delete, data: { confirm: 'Are you sure?' } %></td> 
     </tr> 
    <% end %> 

Das fühlt sich mehr richtig, aber nicht den ganzen Weg gibt, so bin ich nicht wirklich sicher, wie ich das ändern kann es ist korrekter, zumal die Indexansicht, die die Datensätze auflistet, sehr ähnlich ist.

Wie sollte ich dies umgestalten?

Frage 2: My Test nicht

So oder so vergehen will, ist mein Test besteht nicht. Ich schätze, es ist die Art, wie ich meine Eins-zu-Viele-Beziehungen nutze.

test "should get index" do 
    get departments_url 
    assert_response :success 
    end 

Fehler:

DepartmentsControllerTest#test_should_get_index: 
ActionView::Template::Error: undefined method `name' for nil:NilClass 
    app/models/department.rb:6:in `get_library_name' 
    app/views/admin/departments/index.html.erb:21:in `block in _app_views_admin_departments_index_html_erb__1894713831414342893_57284960' 
    app/views/admin/departments/index.html.erb:16:in `_app_views_admin_departments_index_html_erb__1894713831414342893_57284960' 
    test/controllers/departments_controller_test.rb:11:in `block in <class:DepartmentsControllerTest>' 

Antwort

1

Frage 1:

Sie können ganz einfach die Abfrage für die zugehörige Bibliothek Zugriff auf die Zuordnungsverfahren verwenden.

Wenn Sie belong_to :library zu Department hinzugefügt, du bist wirklich zu schaffen nur eine Methode library auf Instanzen von Department genannt, die die entsprechende Abfrage für Sie anruft.

Das gleiche passiert für die has_many, has_one oder has_and_belongs_to_many Verbände, erwarten Sie das Gegenteil passiert.

Anstatt nach Library.find_by(id: department.library_id) zu suchen, macht es das Gegenteil, Department.find_by(library_id: department.library_id).

Alle diese können leicht durch die assoziativen Methoden zugegriffen werden.

department = Department.first 
library = department.library 

Um wieder auf die Frage, persönlich, ich mag die größte Datenmenge, meine Ansichten Belichtungs- und von dort herunter verengt.

würde ich nur ein @department, zur Ansicht schicken und den Namen oder die delegate die Namen von Bibliothek zu Abteilung zeigen, nicht die Mühe, ein Verfahren zu schaffen (mit Vorwahl) ein library_name Verfahren zu erhalten.

<% @departments.each do |department| %> 
    <tr> 
    <td><%= department.name %></td> 
    <td><%= department.description %></td> 
    <td><%= department.library.name %></td> 
    <td><%= link_to 'Show', department %></td> 
    <td><%= link_to 'Edit', edit_department_path(department) %></td> 
    <td><%= link_to 'Destroy', department, method: :delete, data: { confirm: 'Are you sure?' } %></td> 
    </tr> 
<% end %> 

Frage 2:

Leider habe ich nicht viel von einer Antwort. Das Problem ist, dass es wenig Informationen gibt, mit denen man arbeiten kann, aber jetzt sind wir auch mit vielen Methoden verbunden, die senden können, und das Nil kann dominieren, bis es zu deiner Modellmethode kommt.

Ich vermute stark, dass eine Ihrer Abteilungen keine library_id hat, die Ihre Schleife abstürzt, da es von jeder Abteilung abhängt, die eine Bibliothek hat.

EDIT

Frage 3:

die inverse Beziehung zu erhalten, geben Sie einfach department.libraries tun.

In der beschriebenen Situation hatten Sie eine Sammlung von Abteilungen, die sich von einer einzelnen Abteilungsinstanz unterscheidet.

+0

das funktionierte perfekt und eine großartige Erklärung. Ich werde Ihre Antwort korrekt markieren, aber könnten Sie die Umkehrung erklären, wenn ich alle Abteilungen in meine Bibliotheksansicht aufnehmen lassen möchte? Wenn ich das @ libraries-Element überprüfe, das auf "Library.all" zeigt, sehe ich keine Abteilungen. –

+0

Ich habe tatsächlich eine Klasse in meiner Bibliotheksmethode erstellt, um die Abteilungen zu bekommen. '' 'def-Abteilungen departments = Department.where (: library_id => self.id) ende''' –

+0

@ DavidJ.Davis Meine Antwort aktualisiert – fbelanger