Rails: uniqueness of two attributes in the join table causing 500 errors

I have the following models, which basically try to mean that the professor has knowledge for many subjects for a certain level . Subjects are fixed, so new objects will not be created, they will simply be “connected” to the professor through a table of knowledge connections.

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 

I want to have a form that allows the professor to add a topic to his account, and I decided to have a form for knowledge (since I also want to insert a level).

It looks like this:

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

And in the create action of the Knowledges controller, I have the following:

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

I wanted / expected to get ActiveRecord saying that this knowledge cannot be inserted because there is a violation of uniqueness, but nops, I just see 500 in the logs and rollback, but it seems that the execution continues. Therefore, my question is: what am I doing wrong, or how could I improve this model situation? I believe that the form should be connected with the union model, because I want to have the fields of this model on it ... But maybe I'm wrong, and I could do it easily and simply.

EDIT

As indicated in one of the comments, here is the form submission log and 500 errors immediately after the 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 

I added some conditions to the create action, for example:

  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 

And it actually shows right after 500:

 Completed 500 Internal Server Error in 6ms ActiveRecord::RecordInvalid (Validation failed: Subject has already been taken): 

I wonder why an exception occurs instead of just adding errors to the object and letting me manage this situation. Should the following line be followed?

 validates :subject_id, :uniqueness => { :scope => :professor_id } 
+7
source share
2 answers

This error means that you are trying to insert double subject_id / professor_id pairs into this table. Most often, it happens when either subject_id or professor_id null .

Are you sure that the controller receives the correct parameters? I would check the logs to make sure the inserts are what you expect.

0
source

I don’t have enough reputation to comment ... my answer is more than trying than the final answer, sorry.

It seems that the failure is not due to validation errors. You can try to process them in your else block. The following will give you a description of all validation errors (useful for debugging).

 @knowledge.errors.full_messages 

You have not shown what is happening in the “new” action. I suspect errors are occurring here.

Does the same problem (e.g. validation problem) occur in the console? If so, try cleaning your databases (be careful - the following will delete and restore all your databases).

rake db: drop: all db: create: all db: migrate db: test: prepare

Also, if you haven’t done so already, add a transfer index for Knowledge to prevent duplicates from being added to db. eg.

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

All Articles