Rails :Уникальность двух атрибутов в таблице соединений, вызывающая ошибку 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

Я хочу иметь форму, которая позволит профессору добавлять предмет в свою учетную запись, и я решил иметь форму для знаний (, так как я хочу также иметь возможность вставлять уровень ).

Выглядит так:

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

И в действии create контроллера знаний у меня есть это:

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

Я хотел бы/ожидаю получить ActiveRecord , в котором говорится, что это знание не может быть вставлено, потому что есть нарушение уникальности, но нет, я просто вижу 500 в журналах и откат, но кажется выполнение продолжается. Итак, мой вопрос: :Что я делаю неправильно или как я могу улучшить эту ситуацию с моделированием? Я считаю, что форма должна быть связана с моделью соединения, поскольку я хочу, чтобы на ней были поля этой модели... Но, возможно, я ошибаюсь, и я мог бы сделать это проще/чище.

РЕДАКТИРОВАТЬ:

Как просили в одном из комментариев, вот лог отправки формы и ошибка 500 сразу после отката:

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

Я добавил некоторые условия в действие create , например:

  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

И это фактически показывает следующее сразу после 500:

Completed 500 Internal Server Error in 6ms

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

Интересно, почему возникает исключение вместо того, чтобы просто добавить ошибки в объект и позволить мне управлять этой ситуацией. Разве не то, что должна делать следующая строка?

validates :subject_id, :uniqueness => { :scope => :professor_id }
7
задан Nobita 1 July 2012 в 17:02
поделиться