0

Ich habe ein Projekt, das Genealogie beteiligt. Es beginnt mit Fragen an dich (aktueller Benutzer), dann die gleichen Fragen über deinen Vater, dann genau die gleichen Fragen über deine Mutter und geht weiter bis Großeltern beider Seiten.Was ist die beste Design-Praxis zum Erstellen von Tabellen aus dem gleichen Controller mit den gleichen Aktionen

Leider habe ich 3 verschiedene Ansätze und Implementierungen ausprobiert, jedes Mal korrigiere ich vergangene Fehler, da ich ziemlich neu bei Schienen bin.

Ich möchte eine Empfehlung/Anleitung von dieser Gemeinschaft bezüglich des besten Entwurfsansatzes bekommen, dem ich folgen sollte, Designprobleme zu haben.

Also denke ich, dass der beste Weg ist, mit verschiedenen Tabellen zu kommen, um später zu profitieren, wenn ich diese Informationen in einen einzigen Stammbaum stecken muss. Also, eine Tabelle für den aktuellen Benutzer, eine für den Vater, die Mutter, usw. mit einem Modell für jede Tabelle, aber mit einem einzigen Controller, weil ich genau die gleiche html.erb Form habe und jedes Mal ändert die Header die Geschwisterfrage anzupassen.

ich den Fluss und die Aktionen erfolgreich waren wie neu so erstellt, erstellen, zeigen usw., aber mein Problem ist folgendes:

Der Fluss meiner Fragen ist in Folge, und am Ende zeigt einen Stammbaum. Wenn der Benutzer auf "Weiter" klickt, werden die Daten daher in der entsprechenden Tabelle meiner Datenbank gespeichert und der Fluss wird für die nächste Tabelle fortgesetzt.

Ich stecke für mehr als 8 Stunden auf, wie die Methode ändern, die vom Vater auf die Mutter diesen Code machen erstellen:

def create 
    @user = User.new(user_params) 
    if @user.save 
     redirect_to :controller => 'users', :action => 'new_father' 
    else 
     render 'new' 
    end 
    end 

    def user_params 
    params.require(:user).permit(:name, :surname, :dob, :location) 
    end 

wo Benutzer ist der Name Users_Controller und ‚new_father‘ ist eine Ansicht, in derselbe Controller (new_father.html.erb). Es gibt andere Ansichten wie current_user, new_mother usw.

So wird die erste Umleitung erfolgreich erreicht, da Daten in der Datenbank gespeichert werden (erste Umleitung = vom aktuellen Benutzer zu seinem Vater), aber dann kann ich nicht gehen

def create 
     @user = User.new(user_params) 
     if @user.save 
      redirect_to :controller => 'users', :action => 'new_mother' 
     else 
      render 'new' 
     end 
     end 

    def user_params 
    params.require(:user).permit(:name, :surname, :dob, :location) 
    end 

Aber dann brauche ich mehr Controller diese oder eine andere Aktion in demselben Controller ausführen: vom Vater auf der Mutter in dem gleichen Controller und die Form bleibt in der new_father.html.erb Ansicht mit dem folgenden Code gestapelt namens create_mother. Aber ich habe alles mit nicht Erfolg versucht.

Kann mir bitte jemand (zuerst) auf die Redirect_to Methode Best Practice, vor allem, wenn ich mehr Controller mit gleichen Methoden oder den gleichen Controller mit verschiedenen Methoden, oder den gleichen Controller die gleichen Funktionen (Ich habe das versucht und ich bekomme der Fehler "mehr Umleitungen oder Renderings in einer einzigen Funktion") und zweitens, wenn das beste Design für diese spezielle Situation zu folgen, wo ich genau die gleichen Felder und Aktionen, aber in verschiedenen Tabellen mit unterschiedlichen Umleitungen jedes Mal benötigen.

Meine Strecken sind:

Rails.application.routes.draw do 

    # The first page providing information about the current user (novice genealogist). 
    get 'users/new' 

    # The rest of the pages asking information to form the tree. 
    get 'fathers/new_father' 
    get 'mothers/new_mother' 

    # TODO 
    # get 'users/new_grandfather_m' 
    # get 'users/new_grandmother_m' 

    # The input windows that the user lands on need to create a new record in the database. 
    get '/signup',    to: 'users#new' 
    get '/new_father',   to: 'fathers#new_father' 
    get '/new_mother',   to: 'mothers#new_mother' 

    # TODO 
    # get '/new_grandfather_m', to: 'users#new' 
    # get '/new_grandfather_m', to: 'users#new' 

    # This page will serve as the tree showing information from the above input. 
    get '/tree' ,    to: 'users#show' 

    # Used to update the database by creating records with the above info. 
    post '/signup',    to: 'users#create' 
    post '/new_father',   to: 'fathers#create_father' 
    post '/new_mother',   to: 'mothers#create_mother' 

    # TODO 
    # post '/new_grandfather_m', to: 'users#create' 
    # post '/new_grandmother_m', to: 'users#create' 

    # The database of our system. 
    resources :users 

    # The homepage. 
    root 'users#new' 

end 

Die anderen Aktionen sind: (im Grunde hatte ich für jede Relation neuen Controller gemacht)

class FatherController < ApplicationController 

    # Creates a new instance of the user object (not a record). 

    def new_father 
    @father = User.new 
    end 


    # Creates a new record in the database by filling the fields of the new object instance 
    # with data. 

    def create_father 
    @father = User.new(father_params) 
    if @father.save 
     #redirect_to @user 
     redirect_to :controller => 'mothers', :action => 'new_mother' 
    else 
     render 'new_father' 
    end 
    end 


    # A private method to pass the parameters in the new object instance. 

    private 

    def father_params 
    params.require(:user).permit(:name, :surname, :dob, :location) 
    end 


    # Extracts information from the database. 

    def show_father 
    @father = User.find(params[:id]) 
    end 

end 
  • HINWEIS:

I don Ich brauche keine Beziehungen usw., das Wichtigste ist, einen wirklich einfachen Baum zu finden, der das zeigt e Daten des Benutzers und Schienen lernen daher Beziehungen eins zu eins, eins zu vielen, viele zu vielen sind nicht wichtig.

Vielen Dank im Voraus.

+0

Bitte fügen Sie Ihrer Frage den 'new_mother' und' new_father' Aktionscode hinzu. –

+0

Bitte fügen Sie auch Ihre Routen hinzu. –

+0

Vielen Dank für Ihre Antwort. Ich habe die Frage mit dem von Ihnen angeforderten Code aktualisiert, aber es ist nicht wichtig, Relationen einzubeziehen, da dies eine einfache App ist und das Hauptziel die endgültige Ansicht ist, wo es einen einfachen Baum gibt. –

Antwort

1

Sie haben zwei create Aktionen, die Ihrer Beschreibung nach in verschiedenen Controllern gespeichert sind. Beide versuchen, auf das UserController umzuleiten, obwohl das mit dem vorherigen nicht übereinstimmt. Sie sollten Ihre Controller und Routencodes zu Ihrer Frage hinzufügen, um Mehrdeutigkeiten zu vermeiden. Die new_father und new_mother sind nicht die Ansichten Ihres Controllers, sondern die Aktionen. Wenn Sie etwas tun, wie dies am Ende einer Aktion:

redirect_to :controller => 'users', :action => 'new_mother' 

Der Browser wird mit der URL eine Umleitung Status sollte es besuchen nächste, so etwas wie:

Location: http://localhost:3000/users/new_mother 

der Browser macht dann eine Neue Anfrage an diese URL, das heißt, wenn Sie Ihre Routen an Ort und Stelle haben, wird Ihre UserController Aktion new_mother ausgeführt werden. Ihre new_mother und new_father sollten Aktionen innerhalb Ihrer UserController sein, wenn Sie einige Routing-Hacks tun. Für den Fall, dass dies der Fall ist, geschieht dies als eine komplett neue Anfrage, unabhängig von der ersten, die den Umleitungsstatus zurückgegeben hat.

Wenn Sie redirect_to oder render aufrufen, sendet Rails die Antwort noch nicht an den Browser, stattdessen markiert sie die interne Antwortstruktur mit einigen Daten und geht mit dem Rest des Aktionscodes weiter. Erst wenn der vollständige Aktionscode ausgeführt wurde, wird die Antwort zurückgesendet. Durch sein Design beschwert sich Rails, wenn Sie diese Methoden mehr als einmal in Ihrer Aktion aufrufen, da es dies als einen möglichen Fehler im Aktionscode behandelt.


über das Design:

Es gibt Personen und Beziehungen in Ihrer Domäne. Personen haben die gleichen Eigenschaften, sei es ein Benutzer, Vater oder Mutter oder ein anderer Verwandter. Ihre Domäne schreibt nicht vor, dass Personen auf verschiedene Tabellen verteilt werden müssen. In der Tat, was Sie hauptsächlich suchen, ist der Beziehungstyp zwischen Familienmitgliedern. Mutter, Vater, Schwester, Neffe usw. sind Beziehungen zwischen einem Paar Menschen. Es wäre dann sinnvoll, diese Beziehungen als Modell zu präsentieren:

# simplistic representation 
create_table "relations" do |t| 
    t.integer "to_person_id" 
    t.integer "is_person_id" 
    t.string "relation_type" 
end 

relation_type Feld, um den Verwandtschaftstyp als String tragen würde, z.B. 'Vater'.

Obwohl dies ein geeigneter Weg wäre, um eine vollständige Genealogie-Baum-Anwendung zu erstellen, ist es auch komplexer.Es würde single-table has-many-Zuordnungen und rekursive SQL-Abfragen enthalten, die beide ziemlich fortgeschrittene Themen sind.

Es gibt vorhandene Edelsteine, die diese Art von Schema handhaben. Einige von ihnen sind ancestry, acts_as_tree, acts-as-dag.

+0

Ich bevorzuge eine handliche und klare Lösung mit so wenig Zauberei wie möglich, um die MVC dieses Falles mit sogar einem Tisch für jede Person zu verstehen (ich werde zu den Großeltern nicht weiter gehen) und mir sagen, ob es gut ist, ein anderes Modell zu haben für jede Tabelle und einen anderen Controller und die Umleitungen innerhalb der create-Funktionen mit: redirect_to: controller => 'Mütter',: action => 'new_mother' –

+0

Ich aktualisiere auch die Frage mit Code von Routen und Benutzer-Controller –

+0

Der Einfachheit halber und für Lernzwecke ist Ihr Ansatz vollkommen gültig. Es ist in Ordnung, verschiedene Modelle und Controller für "Väter" und "Mütter" zu haben, vor allem, weil Sie nicht vorhaben, über die Großeltern hinauszugehen. In dieser Hinsicht sehen Ihre Controller und Routen gut aus. –

1

Verschiedene Modelle/Tabellen für dieselben Daten zu haben, ist nicht die beste Vorgehensweise. Ich denke, du solltest nur 2 Tische brauchen, um alles zu handhaben (Natürlich eine Tabelle für questions). Eine Tabelle sollte users sein, in der alle Benutzer gespeichert werden. Jeder Benutzer hat den Verweis auf es ist mother und es ist father Es kann durch Self Join/Vererbung erreicht werden. Dann brauchen Sie eine Tabelle für answers In dieser Tabelle werden alle Antworten für alle Benutzer gespeichert. Alle die Antwort, ob sie für mother oder father oder grand parents sind. Sie brauchen nur eine zusätzliche Spalte, um den Typ der Antwort zu unterscheiden, ob es für Mutter/ihn/Vater oder Großeltern ist.

Jeder answer wird dem user gehören, die diese Antwort gab und wird dem Also im Grunde ist hier eine rohe Implementierung für dieses schmea question

gehören.

class User < ActiveRecord::Base 
has_many :answers 
belongs_to :mother , class_name: 'User' , foreign_key: 'mother_id' #This is telling the user belongs to a mother and it's stored in same table. And mother reference will be stored in mother_id column. So user table should have a column mother_id 

belongs_to: father , class_name: 'User', foreign_key: 'father_id' #This is telling the user belongs to a father and it's stored in same table. And father reference will be stored in father_id column. So user table should have a column father_id 

has_many :children ,->(user){ where("users.father_id ? or users.mother_id = ?",user.id)} #Every user can have many children. Whether it's a mother or a father 

def grand_father_from_father_side 
    father && father.father 
end 

def grand_father_from_mother_side 
    mother && mother.father 
end 

#Similary you can get grammy like mother.mother 
end 


class Question < ActiceRecord::Base 
has_many :answers 
end 

class Answer < ActiveRecord::Base 
belongs_to :question 
belongs_to :user 

#There will be a question_for column in answer table which will tell you this answer was posted for which relation i-e Mother , Father or User Himself 

end 

jetzt In Benutzer-Controller ist es ziemlich einfach. Sie brauchen nur eine einzige Ansicht, die für jede Art von Antwort aufgerufen wird, sei es für den Benutzer oder seine Eltern oder seinen Großvater. Legen Sie einfach ein verstecktes Feld in das Formular, das Ihnen den Typ der Antwort sagt, und es wird in der Antworttabelle gespeichert.

Wenn also der Benutzer für seine Mutter antwortet, ist der Wert "Mutter" und so weiter.

Dann können Sie alle Benutzer Antwort mit 'Filter

user.answers.where(answer_type: 'Mother') dies alle Antworten für einen Benutzer zurück, die er für seine Mutter antwortete.

+0

Vielen Dank für Ihre Antwort. Nicht erforderlich, um Beziehungen aufzunehmen, ich bin Anfänger in Schienen und es ist mein allererstes Backend-Rahmenwerk, und ich habe dieses Projekt mit dem Ziel, einen Baum mit diesen Beziehungen zu zeigen.Ich bevorzuge eine handliche und klare Lösung mit so wenig Magie wie möglich, um die MVC dieses Falles mit sogar einem Tisch für jede Person zu verstehen (ich werde nicht weiter zu den Großeltern gehen) und mir sagen, ob es gut ist, ein anderes Modell zu haben jede Tabelle und einen anderen Controller und die Umleitungen innerhalb der create-Funktionen mit: redirect_to: controller => 'Mütter',: Aktion => 'new_mother' –

+0

Ich aktualisiere auch die Frage mit Code von Routen und Benutzer-Controller –

+0

Wie ich bereits erwähnt habe Es ist nicht empfehlenswert, das zu tun, was Sie erreichen möchten. Aber während du Rails lernst, ist es in Ordnung, mehrere Modelle und Controller zu haben und mit ihnen zu spielen. Nach dem Abschluss dieser Aufgabe haben Sie selbst die Idee, warum es keine gute Idee war, es zu tun –

Verwandte Themen