1

私のプロジェクトにはいくつかのモデルがあります。それらのいくつかがあります:QualificationCurriculum. Qualification子供がいます(カリキュラム)。Qualification削除するときに、すべての子を削除することを確認したいと思います。これが私のコードです:

# Table name: qualifications
#
#  id         :integer         not null, primary key
#  subject_id :integer
#  teacher_id :integer
#  created_at :datetime        not null
#  updated_at :datetime        not null
class Qualification < ActiveRecord::Base
  belongs_to :subject
  belongs_to :teacher

  has_many :curriculums, :dependent => :delete_all
  has_many :school_classes, :through => :curriculums
end

#  id               :integer         not null, primary key
#  school_class_id  :integer
#  qualification_id :integer
#  created_at       :datetime        not null
#  updated_at       :datetime        not null
class Curriculum < ActiveRecord::Base
  belongs_to :school_class
  belongs_to :qualification

  has_one :result

  has_many :timetables
end

ご覧のとおり:dependent => :delete_all、資格モデルで使用しようとしました。しかし、うまくいきません。なんで?

更新:

編集時にビューのチェックボックスをオフにして資格を削除します。

<div class="control-group"> 
  <%= f.label :subject_ids, "Teacher can teach such subjects in the school", 
              :class => "control-label" %>               

  <div class="controls">
    <table class="table table-bordered table-striped">
      <thead>
        <tr>
          <th>Choose</th>
          <th>Subject</th>
        </tr>
      </thead>
      <tbody>
        <%= hidden_field_tag "teacher[subject_ids][]", nil %>                         <%# We use hidden field because it doesn't submit unchecked fields. So, we pass nil and nothing will be submitted.%>

        <% @subjects.each do |subject| %>                                             
          <tr>                                                                        
            <td>                                                                      
              <%= check_box_tag "teacher[subject_ids][]",                             # [] brackets tells that this is array.
                                subject.id,                                           # Value of checkbox.
                                @teacher.subject_ids.include?(subject.id),            # Here we automatically check checkboxes.
                                id: dom_id( subject ) %>                              <%# Give unique id for each value. 'dom_id' is Rails helper. We will have ids like: 'subject_1', 'subject_2' and etc. %>
            </td>                                                                     
            <td>                                                                      
              <%= label_tag dom_id( subject ), subject.subject_name %>                <%# Put name of subject. %>
            </td>
          </tr>
        <% end %>
      </tbody>
    </table>
  </div>
 </div>

詳細は次のとおりです。

class Teacher < ActiveRecord::Base  
  has_many :qualifications
  has_many :subjects, :through => :qualifications
end

class Subject < ActiveRecord::Base
  has_many :qualifications
  has_many :teachers, :through => :qualifications  
end

モデルを更新するときの SQL コードは次のとおりです。

Started PUT "/teachers/2" for 127.0.0.1 at 2012-06-03 18:34:44 +0400
Processing by TeachersController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"ZJNNV9/TO6k18O1Ar1kpkU+PWbd7btHm9Tc067iMNO4=", "teacher"=>{"teacher_last_name"=>"Last", "teacher_first_name"=>"First", "teacher_middle_name"=>"Middle", "teacher_sex"=>"m", "teacher_birthday"=>"1980-12-01", "teacher_phone_attributes"=>{"teacher_mobile_number"=>"88283686", "teacher_home_number"=>"5112787", "id"=>"2"}, "teacher_education_attributes"=>{"teacher_education_university"=>"Mmm", "teacher_education_year"=>"1970-01-01", "teacher_education_graduation"=>"Graduated", "teacher_education_speciality"=>"Math", "id"=>"2"}, "teacher_category"=>"1st", "subject_ids"=>["", "4", "3", "1"]}, "commit"=>"Update", "id"=>"2"}
  User Load (0.5ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 2 LIMIT 1
  Teacher Load (0.4ms)  SELECT "teachers".* FROM "teachers" WHERE "teachers"."id" = $1 LIMIT 1  [["id", "2"]]
   (0.1ms)  BEGIN
  Subject Load (0.5ms)  SELECT "subjects".* FROM "subjects" WHERE "subjects"."id" IN (4, 3, 1)
  Subject Load (0.5ms)  SELECT "subjects".* FROM "subjects" INNER JOIN "qualifications" ON "subjects"."id" = "qualifications"."subject_id" WHERE "qualifications"."teacher_id" = 2
  SQL (0.4ms)  DELETE FROM "qualifications" WHERE "qualifications"."teacher_id" = 2 AND "qualifications"."subject_id" = 2
  TeacherPhone Load (0.4ms)  SELECT "teacher_phones".* FROM "teacher_phones" WHERE "teacher_phones"."teacher_id" = 2 LIMIT 1
  TeacherEducation Load (0.4ms)  SELECT "teacher_educations".* FROM "teacher_educations" WHERE "teacher_educations"."teacher_id" = 2 LIMIT 1
   (24.1ms)  COMMIT
Redirected to http://0.0.0.0:3000/teachers
Completed 302 Found in 57ms (ActiveRecord: 27.2ms)
4

3 に答える 3

2

試す:

:dependent => :destroy 

それ以外の:dependent => :delete_all

于 2012-06-02T16:34:12.393 に答える
1

これがあなたがしていることかどうかはわかりませんが、 :dependent => :delete_all を使用して依存関係を削除できます

delete を使用する代わりに、コントローラで destroy を使用しました。

例: 代わりに: Qualification.delete(params[:id])

    Use this:
         Qualification.destroy(params[:id])

お役に立てれば。=)

于 2012-10-08T04:52:32.363 に答える
0

「レール3ウェイ」はそれを言います -

(pg 187) クリア

外部キー フィールドをクリアすることにより、この関連付けからすべてのレコードをトランザクション的に削除します (delete を参照)。関連付けが :delete_all に設定された :dependent オプションで構成されている場合、delete_all が呼び出されます。同様に、:dependent オプションが :destroy_all に設定されている場合、destroy_all メソッドが呼び出されます。

delete(*records) および delete—すべて

delete および delete_all メソッドは、それぞれ指定された関連付けまたはすべての関連付けを切断するために使用されます。どちらの方法もトランザクション的に動作します。パフォーマンス上の理由から、delete_all を呼び出すと、ID を取得するために、関連付けられたオブジェクトのコレクション全体が最初にメモリに読み込まれることに注意してください。次に、現在関連付けられているすべてのオブジェクトの外部キーを nil に設定する SQL UPDATE を実行し、オブジェクトを親から効果的に関連付け解除します。関連付け全体をメモリにロードするため、関連付けられたオブジェクトの非常に大きなコレクションでこのメソッドを使用することはお勧めできません。

ノート

delete および delete_all メソッドの名前は誤解を招く可能性があります。デフォルトでは、データベースから何も削除しません。関連付けられたレコードの外部キー フィールドをクリアすることによって関連付けを切断するだけです。この動作は、デフォルトで :nullify に設定されている :dependent オプションに関連しています。:delete または :destroy に設定された :dependent オプションを使用して関連付けが構成されている場合、関連付けられているレコードは実際にはデータベースから削除されます。

:dependent => :destroy または :delete

オプションの値に応じて、関連する所有者レコードを破棄するか、データベースから削除するかのルールを指定します。トリガーされると、:destroy は従属オブジェクトのコールバックを呼び出しますが、:delete は呼び出しません。

このオプションの使用は、has_one / belongs_to のペアリングで意味がある場合があります。ただし、has_many / belongs_to 関係でこの動作が必要になる可能性はほとんどありません。そのようにコーディングするのは意味がないようです。さらに、所有者レコードの :dependent オプションが対応する has_many アソシエーションに設定されている場合、1 つの関連付けられたレコードを破棄すると、その兄弟すべてが破棄されるという波及効果があります。

于 2012-10-08T05:09:44.143 に答える