2017-05-18 4 views
0

Ich baue eine Familienalbum-Anwendung mit Ruby on Rails. Ich habe zwei Haupttafeln: "Familien" und "Mitglieder". Familien haben viele Mitglieder.Rails - Verweis auf andere Mitglieder der gleichen Tabelle

I wenn ich ein neues "Mitglied" einer "Familie" erstelle, versuche ich, diese neue Mitgliederbeziehung zum ursprünglichen Mitglied zu verfolgen. Mit meiner App können Sie ein Originalmitglied erstellen. Anschließend müssen alle anderen Mitglieder auf den Wiedergabeseiten eines vorhandenen Mitglieds erstellt werden. Die Idee ist, dass keine neuen Mitglieder zu der Familie hinzugefügt werden dürfen, ohne dass eine Beziehung zu einem bestehenden Mitglied besteht. Dadurch werden Floater-Mitglieder vermieden, die nicht mit anderen Personen verwandt sind.

Ich habe eine Spalte namens "parent_id." Wenn ein neues Mitglied erstellt wird, können Sie die ID des aktuellen Mitglieds (Formular befindet sich in der Ansicht "Mitglieder anzeigen") als übergeordnete ID für das neue Mitglied hinzufügen. Dies verknüpft die Datensätze, sodass sie später referenziert werden können.

Meine Frage ist ziemlich einfach. In der Showansicht eines Mitglieds möchte ich eine Tabelle anzeigen, in der alle Mitglieder angezeigt werden, die eine parent_id == die ID des aktuellen Mitglieds haben. Ziemlich einfach, aber ich kann es nicht zur Arbeit bringen. Das ist, was ich habe jetzt:

<table class="table table-striped"> 
     <tr> 
      <td>First</td> 
      <td>Last</td> 
      <td>Birthplace</td> 
     </tr> 
     <% @members.where("parent_id == @member.id").each do |p| %> 
      <tr> 
       <td><%= p.first_name %></td> 
       <td><%= p.last_name %></td> 
       <td><%= p.birthplace %></td> 
      </tr> 
     <% end %> 
    </table> 

Dies ist der Fehler dieser Code führt:

SQLite3::SQLException: near ".": syntax error: SELECT "members".* FROM "members" WHERE "members"."family_id" = ? AND (parent_id == @member.id) 

Hier ist die Show Aktion in meinen Gliedern Controller:

def show 
    @family = Family.find(params[:family_id]) 
    @member = Member.find(params[:id]) 
    @new = Member.new 
    @members = @family.members 
end 

Hier ist das Schema für meine zwei Tabellen:

create_table "families", force: :cascade do |t| 
t.string "title" 
t.datetime "created_at", null: false 
t.datetime "updated_at", null: false 
end 

create_table "members", force: :cascade do |t| 
t.string "first_name" 
t.string "last_name" 
t.string "birthplace" 
t.datetime "created_at", null: false 
t.datetime "updated_at", null: false 
t.integer "family_id" 
t.integer "parent_id" 
t.integer "child_id" 
t.integer "sibling_id" 
end 
+0

Ihr Domain-Modell ist einfach nicht schneiden gehen. Sie brauchen eine Reihe von Join-Tabellen, anstatt nur alles in zwei Tabellen zu stauen. Zum Beispiel erlaubt Ihr Modell keinem Mitglied mehr Geschwister zu haben oder zu mehreren Familien zu gehören. Sie müssen sich über selbstreferenzielle Assoziationen informieren und zum Zeichenbrett zurückkehren. – max

Antwort

1

Sie versuchen, auf ein id-Attribut innerhalb des Objekts @members zuzugreifen, das wahrscheinlich ein Modell ActiveRecord_Associations_CollectionProxy aus dem Modell Member ist.

Wenn Sie eine @members.inspect machen, werden Sie jedes Element darin sehen, da ein Array-Wert eine id hat, aber nicht das Objekt selbst.

Sie könnten jedes member id-Attribut, wenn man jedes Element durchlaufen und dann in dieser Art und Weise sind Sie in der Lage den Vergleich parent_id = member.id zu machen, die, wenn Sie 'parent_id = ?', member.id SQLi zu vermeiden tun sicherer sein könnten.

Aber ich denke, Sie einfacher, die Mitglieder auf @members seine Attribute nur zu vergleichen prüfen könnten:

<% @members.each do |member| %> 
    <% if member.parent_id == member.id %> 
    <tr> 
     <td><%= member.first_name %></td> 
     <td><%= member.last_name %></td> 
     <td><%= member.birthplace %></td> 
    </tr> 
    <% end %> 
<% end %> 
Verwandte Themen