7

tengo los siguientes modelos, que básicamente están tratando de significar que un profesor tiene conocimiento de muchos temas para un nivel particular. Las asignaturas son fijas, por lo que no se crearán nuevos temas, solo habrá "relación" con un profesor a través de la tabla de unión de conocimiento.Rieles: Singularidad de dos atributos en tabla de unión causando error 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 

Quiero tener una forma que permitirá a un profesor para añadir un objeto a su cuenta, y yo decidimos tener una forma de conocimiento (como yo quiero ser capaz de insertar un nivel demasiado).

Parece que este:

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

Y en el crear acción del controlador de Conocimientos tengo esto:

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

me gustaría/esperar para obtener una ActiveRecord diciendo que este conocimiento no se puede insertar porque hay una violación de unicidad, pero nops, solo veo 500 en los registros y una reversión, pero parece que la ejecución continúa. Entonces mi pregunta es: ¿Qué estoy haciendo mal o cómo podría mejorar esta situación de modelado? Creo que la forma debe estar relacionada con el modelo de combinación ya que quiero tener campos de ese modelo ... Pero tal vez estoy equivocado, y podría hacerlo de una manera fácil/más limpia.

EDITAR:

Como se pidió en uno de los comentarios, aquí está el registro de la presentación de la forma y el error 500 justo después de la reversión:

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 

he añadido algunas condiciones en el crear acción, así:

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 

y este espectáculo en realidad s la siguiente justo después de la 500:

Completed 500 Internal Server Error in 6ms 

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

Me pregunto por qué la excepción se lanza en lugar de limitarse a añadir los errores en el objeto y dejar a manejar esa situación. ¿No es lo que debería estar haciendo la siguiente línea?

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

Por favor, publique los registros que conducen a 500. Eso sería útil. – prasvin

+0

registros se han publicado :) – Nobita

+0

Sí, los errores deberían haberse agregado en el objeto. No creo que eso esté causando el error 500. Puede detener la ejecución antes de crear la línea 'if @ knowledge.save' en KnowledgesController #, usando depurador o palanca. Luego intente con '@ knowledge.save' y' @ knowledge.save! 'Solo para confirmar que los errores de validación han sido incorporados en' @ knowledge'. Puede verificar eso incluso desde la consola. Además, ¿puede por favor publicar la esencia de todo el seguimiento de la pila? Tengo una fuerte sensación de que esto no se debe a la validación de la singularidad. – prasvin

Respuesta

0

Ese error significa que está intentando insertar duplicados subject_id/professor_id pares en esa tabla. La mayoría de las veces ocurre cuando subject_id o professor_id es null.

¿Está seguro de que el controlador está obteniendo los parámetros correctos? Verificaría los registros para asegurarme de que los insertos son lo que esperarías.

0

No tengo suficiente reputación para comentar ... mi respuesta es más algunas cosas que probar que una respuesta definitiva, lo siento.

Parece que el guardado está fallando debido a errores de validación. Puedes tratar de manejarlos en tu bloque 'else'. Lo siguiente le dará una descripción de todos los errores de validación (útil para la depuración).

@knowledge.errors.full_messages 

No ha demostrado lo que está sucediendo en la acción 'nueva'. Sospecho que aquí es donde están ocurriendo los errores.

¿Se produce el mismo problema (es decir, el problema de validación) en la consola?Si es así, intente limpiar sus bases de datos (tenga cuidado; lo siguiente borrará & reconstruya todas sus bases de datos).

rake db: caída: todo db: crear: todo db: migrate db: test: preparar

Además, si no lo ha hecho, añadir un índice a la migración para el Conocimiento para evitar duplicados que se agregan a la base de datos. p.ej.

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