7

Ich habe die folgenden Modelle, die im Grunde zu verstehen versuchen, dass ein ProfessorWissen vieler Themen für eine bestimmte Ebene hat. Die Fächer sind festgelegt, so dass keine neuen Fächer erstellt werden, sondern nur durch die Wissensjoin-Tabelle mit einem Professor "verbunden" werden.Rails: Einmaligkeit von zwei Attributen in Join-Tabelle verursachen Fehler 500

class Subject < ActiveRecord::Base 
    # Self Associations 
    has_many :subcategories, :class_name => "Subject" 
    belongs_to :category, :class_name => "Subject",:foreign_key => "parent_id" 

    # Associations 
    has_many :knowledges 
    has_many :professors, :through => :knowledges 
end 


class Professor < ActiveRecord::Base 
    # Associations 
    has_many :knowledges 
    has_many :subjects, :through => :knowledges 
    ... 
end 

class Knowledge < ActiveRecord::Base 
    # Associations 
    belongs_to :professor 
    belongs_to :subject 
    has_one :level 

    attr_accessible :subject_id, :professor_id 

    validates :subject_id, :uniqueness => { :scope => :professor_id } 
end 

Ich möchte eine Form haben, die einen Professor lassen wird ein Thema sein Konto hinzuzufügen, und ich beschlossen, eine Form für ein Wissen haben (wie ich will auch eine Ebene einfügen können).

Es sieht wie folgt aus:

<%= simple_form_for @knowledge,:url => professor_knowledges_path, :html => { :class => 'form-horizontal' } do |f| %> 
    <div class="control-group select optional"> 
     <%= label_tag "Subject Type", nil, :class => "select optional control-label"%> 
     <div class="controls"> 
    <%= select_tag "Parent Subject", options_from_collection_for_select(@parent_subjects, "id", "name"), :id => "knowledge_parent_subject" %> 
     </div> 
    </div> 
    <%= f.input :subject_id, :collection => @subjects, :label => "Subject" %> 
    <%= f.input :level %> 
    <%= f.button :submit, t('add_form'),:class => 'btn-primary' %> 
<% end %> 

Und in der schaffen Wirkung des Knowledges Controller Ich habe dies:

def create 
    @knowledge = Knowledge.create(:professor_id => current_professor.id, :subject_id => params[:knowledge][:subject_id]) 
    end 

Ich möchte/erwarten ein Active zu bekommen sagen dass dieses Wissen nicht eingefügt werden kann, weil es eine Eindeutigkeitsverletzung gibt, aber nops, ich sehe nur 500 in den Protokollen und ein Rollback, aber es scheint, dass die Ausführung weitergeht. Meine Frage ist also: Was mache ich falsch oder wie könnte ich diese Modellierungssituation verbessern? Ich glaube, das Formular muss mit dem Join-Modell in Beziehung stehen, da ich Felder dieses Modells darauf haben möchte ... Aber vielleicht liege ich falsch, und ich könnte es auf eine einfache/sauberere Weise tun.

EDIT:

Wie in einer der Kommentare gefragt, hier ist das Protokoll der Einreichung des Formulars und der 500-Fehler direkt nach dem Rollback:

Started POST "/professors/1/knowledges" for 127.0.0.1 at 2012-07-01 00:45:39 -0700 
Processing by KnowledgesController#create as HTML 
    Parameters: {"utf8"=>"✓", "authenticity_token"=>"4JVyxWnIh37kyBwLwLGTHk/znsI1c5wrJvaWjKKT5tM=", "Parent Subject"=>"1", "knowledge"=>{"subject_id"=>"1"}, "commit"=>"Añadir", "professor_id"=>"1"} 
    Professor Load (0.4ms) SELECT `professors`.* FROM `professors` WHERE `professors`.`id` = 1 LIMIT 1 
Completed 500 Internal Server Error in 4ms 

Ich habe einige Bedingungen in der erstellen Aktion, wie folgt aus:

def create 
    @knowledge = Knowledge.new(:professor_id => current_professor.id, :subject_id => params[:knowledge][:subject_id]) 
    if @knowledge.save 
     flash[:notice] = "Success..." 
     redirect_to professor_path(current_professor) 
    else 
     render :action => 'new' 
    end 
    end 

Und tatsächlich zeigen die s nach rechts nach dem 500:

Completed 500 Internal Server Error in 6ms 

ActiveRecord::RecordInvalid (Validation failed: Subject has already been taken): 

Ich frage mich, warum die Ausnahme nur statt angehoben wird, um die Fehler in das Objekt hinzufügen und lassen Sie mich diese Situation verwalten. Was sollte die folgende Zeile nicht tun?

+0

Bitte posten Sie die Protokolle, die zu 500 führen. Das wäre hilfreich. – prasvin

+0

Protokolle wurden veröffentlicht :) – Nobita

+0

Ja, die Fehler sollten in das Objekt hinzugefügt worden sein. Ich glaube nicht, dass das den 500 Fehler verursacht. Können Sie die Ausführung vor 'if @ knowledge.save' Zeile in KnowledgesController # create stoppen, mit Debugger oder PRY. Dann versuchen Sie '@ knowledge.save' und' @ knowledge.save! 'Nur um zu bestätigen, dass die Validierungsfehler in' @ knowledge' eingebettet wurden. Sie könnten das sogar von der Konsole aus überprüfen. Auch können Sie bitte einen Kern des gesamten Stack-Trace veröffentlichen. Ich habe das starke Gefühl, dass dies nicht auf die Bestätigung der Einzigartigkeit zurückzuführen ist. – prasvin

Antwort

0

Dieser Fehler bedeutet, dass Sie doppelte subject_id/professor_id Paare auf die Tabelle einfügen möchten. Meistens passiert, wenn entweder subject_id oder professor_idnull ist.

Sind Sie sicher, dass der Controller die richtigen Parameter erhält? Ich würde die Protokolle überprüfen, um sicherzustellen, dass die Einsätze das sind, was Sie erwarten würden.

0

Ich habe nicht genug Ruf zu kommentieren ... meine Antwort ist mehr Dinge zu versuchen als eine definitive Antwort, sorry.

Es scheint, als ob die Sicherung aufgrund von Validierungsfehlern fehlschlägt. Sie können versuchen, mit denen in Ihrem 'else' Block umzugehen. Im Folgenden erhalten Sie eine Beschreibung aller Validierungsfehler (nützlich für das Debugging).

@knowledge.errors.full_messages 

Sie haben nicht gezeigt, was in der 'neuen' Aktion passiert. Ich vermute, dass hier die Fehler auftreten.

Tritt das gleiche Problem (d. H. Das Validierungsproblem) in der Konsole auf?Wenn dies der Fall ist, versuchen Sie, Ihre Datenbanken zu bereinigen (Achtung, das folgende wird & löschen, um alle Ihre Datenbanken neu aufzubauen).

rake db: drop: alle db: create: alle db: Migration db: test: Vorbereitung

Auch, wenn Sie nicht bereits haben, um einen Index zu Migration für Wissen hinzufügen zu verhindern Duplikate werden zur Datenbank hinzugefügt. z.B.

add_index :knowledges, [ :professor_id, :subject_id ], unique: true