Rails 3 - 依赖=> :delete_all不起作用。为什么?

时间:2012-06-02 16:23:55

标签: ruby-on-rails ruby ruby-on-rails-3 postgresql

我的项目中我的模型很少。其中有一些:QualificationCurriculumQualification有孩子(课程)。我想确保当我删除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。但它不起作用。为什么呢?

UPD:

我通过在编辑时取消选中视图中的复选框来删除资格:

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

3 个答案:

答案 0 :(得分:2)

尝试:

:dependent => :destroy 

而不是:dependent => :delete_all

答案 1 :(得分:1)

不确定这是否就是您正在做的事情,但我可以使用:dependent =&gt;删除家属。 :DELETE_ALL

我没有使用删除,而是在我的控制器中使用了destroy。

实施例:         代替:              Qualification.delete(PARAMS [:ID])

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

希望这会有所帮助。 =)

答案 2 :(得分:0)

“轨道3路”说 -

(第187页) 明确

通过清除外键以事务方式删除此关联中的所有记录 字段(见删除)。如果关联配置为:dependent选项设置为 :delete_all,然后调用delete_all。同样,如果:dependent选项设置为 :destroy_all,然后调用destroy_all方法。

删除(*记录)和删除全部

delete和delete_all方法用于切断指定的关联或全部 他们分别。两种方法都以事务方式运行 值得注意的是,出于性能原因,调用delete_all会首先加载 整个关联对象的集合到内存中以获取它们的ID。然后呢 执行SQL UPDATE,将所有当前关联对象的外键设置为nil, 有效地将他们与父母分开。由于它将整个关联加载到内存中,因此将此方法与极大的关联对象集合一起使用是不明智的。

请注意

delete和delete_all方法的名称可能会产生误导。默认情况下,他们 不要从数据库中删除任何内容 - 它们只通过清除外部来切断关联 相关记录的关键字段。此行为与:dependent选项有关 默认为:nullify。如果关联配置为:dependent选项设置为 :delete或:destroy,然后实际上将从数据库中删除关联的记录。

:dependent =&gt; :destroy或:delete

指定应销毁或仅删除关联所有者记录的规则 数据库,取决于选项的值。触发时::destroy将调用 依赖的回调,而:删除不会。

在has_one / belongs_to配对中使用此选项可能有意义。然而, 你不太可能在has_many / belongs_to关系中想要这种行为; 以这种方式编写代码似乎没有意义。另外,如果是主人 记录具有:依赖选项设置在相应的has_many关联上,然后 摧毁一个相关记录会产生摧毁其所有兄弟姐妹的涟漪效应。