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 }
Por favor, publique los registros que conducen a 500. Eso sería útil. – prasvin
registros se han publicado :) – Nobita
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