7

私は次のモデルを持っています。これは基本的に、教授が特定のレベルの多くの科目の知識を持っていることを意味しようとしています。科目は固定されているため、新しい科目は作成されず、知識結合テーブルを介して教授に「関連付けられる」だけです。

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

そして、Knowledges コントローラーのcreateアクションには、次のようなものがあります。

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

一意性違反があるため、このナレッジを挿入できないというActiveRecordを取得したい/期待していますが、ログに 500 とロールバックが表示されるだけですが、実行は続いているようです。私の質問は次のとおりです。私は何を間違っているのでしょうか、またはこのモデリングの状況をどのように改善できますか? そのモデルのフィールドを作成したいので、フォームを結合モデルに関連付ける必要があると思います...しかし、おそらく私は間違っているので、簡単でクリーンな方法で行うことができます。

編集

コメントの1つで尋ねられたように、フォームの送信とロールバック直後の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

次のように、作成アクションにいくつかの条件を追加しました。

  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 }
4

2 に答える 2

0

コメントするには十分な評判がありません...私の答えは、決定的な答えというよりも、試してみることです。申し訳ありません。

検証エラーのために保存に失敗しているようです。「else」ブロックでそれらを処理することができます。以下は、すべての検証エラーの説明です (デバッグに役立ちます)。

@knowledge.errors.full_messages

「新しい」アクションで何が起こっているかを示していません。ここでエラーが発生していると思われます。

コンソールでも同じ問題 (つまり、検証の問題) が発生しますか? その場合は、データベースを消去してみてください (注意してください - 以下はすべてのデータベースを消去して再構築します)。

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

また、まだ行っていない場合は、ナレッジの移行にインデックスを追加して、重複がデータベースに追加されるのを防ぎます。例えば

    add_index :knowledges, [ :professor_id, :subject_id ], unique: true
于 2012-07-02T19:01:09.563 に答える
0

このエラーは、そのテーブルに重複したsubject_id/professor_idペアを挿入しようとしていることを意味します。ほとんどの場合、subject_idまたはprofessor_idがの場合に発生しますnull

コントローラーが正しいパラメーターを取得していると確信していますか? ログをチェックして、挿入が期待どおりであることを確認します。

于 2012-07-07T05:36:12.350 に答える