2012-06-30 29 views
7

mam następujące modele, które w zasadzie starają się oznaczać, że profesor ma wiedzę wielu przedmiotów dla konkretnego poziomie. Tematy są ustalone, więc nie będzie nowych przedmiotów stworzonych, będzie tylko "powiązany" z profesorem poprzez tabelę łączenia wiedzy.szyn: Wyjątkowość dwóch atrybutów w tabeli dołączyć powodując błąd 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 

chcę mieć formę, która pozwoli profesora aby dodać temat do swojego konta i ja zdecydowaliśmy się na formę do wiedzy (jak chcę, aby móc wstawić poziom zbyt).

Wygląda to tak:

<%= 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 %> 

A w tworzyć działanie kontrolera Knowledges mam to:

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

Chciałbym/oczekiwać, aby uzyskać ActiveRecord mówiąc że tej wiedzy nie można wstawić, ponieważ istnieje naruszenie wyjątkowości, ale nie, widzę tylko 500 w logach i rollbackach, ale wygląda na to, że egzekucja trwa. Moje pytanie brzmi: co robię źle, lub jak mogę poprawić tę sytuację modelowania? Uważam, że formularz musi być powiązany z modelem łączenia, ponieważ chcę mieć na nim pola tego modelu ... Ale może się mylę i mogłem to zrobić w łatwy/czysty sposób.

EDIT:

Jak zapytałem w jednym z komentarzy, tutaj jest dziennik składania formularza i błąd 500 tuż po wycofywania:

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 

dodałem pewne warunki w tworzyć działania, tak:

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 

I to faktycznie pokazać s następujące zaraz po 500:

Zastanawiam się, dlaczego wyjątek jest podniesiony zamiast tylko dodanie błędów do obiektu i pozwól mi zarządzać tą sytuacją. Czy nie jest to, co powinien zrobić poniższy wiersz?

validates :subject_id, :uniqueness => { :scope => :professor_id } 
+0

Proszę zaksięgować logi, które prowadzą do 500. Byłoby to pomocne. – prasvin

+0

logi zostały wysłane :) – Nobita

+0

Tak, błędy powinny być dodane do obiektu. Nie sądzę, że powoduje to błąd 500. Czy możesz zatrzymać wykonywanie przed wierszem 'if @ knowledge.save' w KnowledgesController # create, przy użyciu debuggera lub podważenia. Następnie spróbuj '@ knowledge.save' i' @ knowledge.save! ', Aby potwierdzić, że błędy walidacji zostały osadzone w' @ knowledge'. Można to sprawdzić nawet z konsoli. Czy możesz również opublikować opis całego śladu stosu. Mam silne przeczucie, że nie wynika to z walidacji wyjątkowości. – prasvin

Odpowiedz

0

Błąd ten oznacza, że ​​próbujesz wstawić zduplikowanych subject_id/professor_id pary na stole. Najczęściej zdarza się, gdy subject_id lub professor_id jest .

Czy na pewno sterownik uzyskuje prawidłowe parametry? Sprawdziłbym dzienniki, aby upewnić się, że wstawki są takie, jakich można się spodziewać.

0

Nie mam wystarczająco dużo reputacji, aby skomentować ... moja odpowiedź to więcej rzeczy do wypróbowania niż ostateczna odpowiedź, przepraszam.

Wygląda na to, że zapis nie działa z powodu błędów sprawdzania poprawności. Możesz spróbować poradzić sobie z tymi w bloku "else". Poniżej znajdziesz opis wszystkich błędów sprawdzania poprawności (przydatne przy debugowaniu).

@knowledge.errors.full_messages 

Nie pokazałeś, co dzieje się w akcji "nowej". Podejrzewam, że to właśnie tam występują błędy.

Czy ten sam problem występuje (np. Problem z weryfikacją) w konsoli?Jeśli tak, spróbuj wyczyścić swoje bazy danych (uwaga - poniższe skasuje & odbudować wszystkie bazy danych).

rake db: Spadek: wszystkie db: create: wszystkie db: migrować db: test: przygotować

Ponadto, jeśli jeszcze tego nie zrobiłeś, dodać indeks do migracji na wiedzy, aby zapobiec duplikaty dodawane do bazy danych. na przykład

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