Destroy有许多通过关联删除该id的所有关联



这是几个星期前的工作,但在添加paper_trail版本控制后,我现在做更新时有以下错误:

一个微型有许多雕塑家通过雕刻表。当我通过删除关联的雕塑家来编辑Miniature,然后提交更新时,Miniatures控制器会破坏属于删除的雕塑家的sculpdings表中的所有条目,而不仅仅是更新的Miniature的条目。

这是我的迷你更新动作

def update
    @miniature = Miniature.find(params[:id])
     if params[:miniature][:"release_date(2i)"] == ''
      # no month is given, insert fake month and day
      params[:miniature][:"release_date(2i)"] = '1'
      params[:miniature][:"release_date(3i)"] = '1'
      mask = 4 # 100
    elsif params[:miniature][:"release_date(3i)"] == ''
      # no day is given, insert a fake day
      params[:miniature][:"release_date(3i)"] = '1'
      mask = 6 # 110
    else
      # full-date
      mask = 7 # 111
    end
    if params[:sculptors][:id]
      ## Convert ["", "1","2","4","8"] to [1,2,4,8]
      params[:sculptors][:id] = params[:sculptors][:id].reject(&:empty?).map(&:to_i) 
      ## Get the sculptor_id from sculptings already present in database [1,2,5,6] 
      old_sculptors = @miniature.sculptings.pluck(:sculptor_id)
      ## Find the new sculptors to be added [1,2,4,8] - [1,2,5,6] = [4,8]
      new_sculptors = params[:sculptors][:id] - old_sculptors 
      ## Find the old_sculptors to be deleted [1,2,5,6] - [1,2,4,8] = [5,6]
      old_sculptors = old_sculptors - params[:sculptors][:id] 
      ## Build new_sculptors [4,8]
      new_sculptors.each do |sculptor|
        @miniature.sculptings.build(:sculptor_id => sculptor)
      end
      ## Delete old_sculptors [5,6]
      Sculpting.destroy_all(:sculptor_id => old_sculptors)
    end
    if @miniature.update_attributes(miniature_params.merge(date_mask: mask))
      flash[:success] = "Miniature updated. #{undo_link}"
      redirect_to @miniature
    else
      render 'edit'
    end
  end

这是表单的相关部分(它使用了多选)

<div class="control-group">
        <%= f.fields_for(@sculpting) do |scf| %>
          <%= scf.label :sculptors, 'Sculpted by', class: "control-label" %>
            <div class="controls">
              <%= collection_select( :sculptors, :id, @all_sculptors, :id, :fullname, 
                   {:selected => @miniature.sculptors.map(&:id)}, 
                   {class: 'multiselect', multiple: true}) %>
            </div>
        <% end %>
      </div>

这是一个更新的日志输出,我所做的就是从Miniature 43中删除与雕塑家6的关联,但正如你所看到的,它也删除了与雕塑家6的所有其他关联,那些与Miniatures 42和41。

Started PATCH "/miniatures/43" for 127.0.0.1 at 2014-06-04 15:43:57 +0100
Processing by MiniaturesController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"xnfOwotMS39buQFCYnUqZTvFajc0hlz+LIVo4cN02q0=", "miniature"=>{"name"=>"A Aa Perry", "material"=>"Hard Plastic", "pcode"=>"", "release_date(1i)"=>"", "release_date(2i)"=>"", "release_date(3i)"=>"", "set"=>"0", "quantity"=>"", "random"=>"0", "notes"=>"", "comment"=>"Removed sclptr"}, "manufacturers"=>{"id"=>["", "1"]}, "scales"=>{"id"=>["", "3"]}, "sculptors"=>{"id"=>[""]}, "commit"=>"Save changes", "id"=>"43"}
  User Load (0.5ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 4 ORDER BY "users"."id" ASC LIMIT 1
  Miniature Load (0.3ms)  SELECT "miniatures".* FROM "miniatures" WHERE "miniatures"."id" = ? LIMIT 1  [["id", "43"]]
   (0.4ms)  SELECT "sculptings"."sculptor_id" FROM "sculptings" WHERE "sculptings"."miniature_id" = ?  [["miniature_id", 43]]
  Sculpting Load (0.5ms)  SELECT "sculptings".* FROM "sculptings" WHERE "sculptings"."sculptor_id" IN (6)
   (0.1ms)  begin transaction
  SQL (0.5ms)  DELETE FROM "sculptings" WHERE "sculptings"."id" = ?  [["id", 46]]
  SQL (0.5ms)  INSERT INTO "versions" ("created_at", "event", "item_id", "item_type", "object", "whodunnit") VALUES (?, ?, ?, ?, ?, ?)  [["created_at", Wed, 04 Jun 2014 14:43:57 UTC +00:00], ["event", "destroy"], ["item_id", 46], ["item_type", "Sculpting"], ["object", "---nid: 46nsculptor_id: 6nminiature_id: 41ncreated_at: 2014-06-04 11:17:26.000000000 Znupdated_at: 2014-06-04 11:17:26.000000000 Zn"], ["whodunnit", 4]]
  PaperTrail::Version Load (0.1ms)  SELECT "versions".* FROM "versions" WHERE "versions"."item_id" = ? AND "versions"."item_type" = ? ORDER BY versions.created_at ASC, versions.id ASC  [["item_id", 46], ["item_type", "Sculpting"]]
   (3.6ms)  commit transaction
   (0.2ms)  begin transaction
  SQL (0.4ms)  DELETE FROM "sculptings" WHERE "sculptings"."id" = ?  [["id", 47]]
  SQL (0.3ms)  INSERT INTO "versions" ("created_at", "event", "item_id", "item_type", "object", "whodunnit") VALUES (?, ?, ?, ?, ?, ?)  [["created_at", Wed, 04 Jun 2014 14:43:57 UTC +00:00], ["event", "destroy"], ["item_id", 47], ["item_type", "Sculpting"], ["object", "---nid: 47nsculptor_id: 6nminiature_id: 42ncreated_at: 2014-06-04 14:42:07.000000000 Znupdated_at: 2014-06-04 14:42:07.000000000 Zn"], ["whodunnit", 4]]
  PaperTrail::Version Load (0.1ms)  SELECT "versions".* FROM "versions" WHERE "versions"."item_id" = ? AND "versions"."item_type" = ? ORDER BY versions.created_at ASC, versions.id ASC  [["item_id", 47], ["item_type", "Sculpting"]]
   (3.3ms)  commit transaction
   (0.1ms)  begin transaction
  SQL (0.4ms)  DELETE FROM "sculptings" WHERE "sculptings"."id" = ?  [["id", 48]]
  SQL (0.3ms)  INSERT INTO "versions" ("created_at", "event", "item_id", "item_type", "object", "whodunnit") VALUES (?, ?, ?, ?, ?, ?)  [["created_at", Wed, 04 Jun 2014 14:43:57 UTC +00:00], ["event", "destroy"], ["item_id", 48], ["item_type", "Sculpting"], ["object", "---nid: 48nsculptor_id: 6nminiature_id: 43ncreated_at: 2014-06-04 14:42:31.000000000 Znupdated_at: 2014-06-04 14:42:31.000000000 Zn"], ["whodunnit", 4]]
  PaperTrail::Version Load (0.1ms)  SELECT "versions".* FROM "versions" WHERE "versions"."item_id" = ? AND "versions"."item_type" = ? ORDER BY versions.created_at ASC, versions.id ASC  [["item_id", 48], ["item_type", "Sculpting"]]
   (2.5ms)  commit transaction
   (0.1ms)  begin transaction
   (0.2ms)  commit transaction
  PaperTrail::Version Load (0.4ms)  SELECT "versions".* FROM "versions" WHERE "versions"."item_id" = ? AND "versions"."item_type" = ? ORDER BY versions.created_at DESC, versions.id DESC LIMIT 1  [["item_id", 43], ["item_type", "Miniature"]]
Redirected to http://localhost:3000/miniatures/43
Completed 302 Found in 166ms (ActiveRecord: 15.9ms)

就像我说的,几个星期前这一切都工作得很好,但是从那以后我添加了太多的paper_trail版本控制,我真的不想恢复到旧版本。我也不确定问题出在哪里。在我让它工作之后,被困在上面非常令人沮丧。如有任何帮助,非常感谢。

在重读和重读更新操作之后,我认为很可能

Sculpting.destroy_all(:sculptor_id => old_sculptors)

不再局限于

定义的雕刻线
old_sculptors = @miniature.sculptings.pluck(:sculptor_id)

并且可能需要再次限制为当前的@miniature。

我改成

Sculpting.where(:miniature_id => @miniature.id).destroy_all(:sculptor_id => old_sculptors)

,问题解决了。

我很确定它最初是按预期工作的,但现在似乎不可能了。它一定总是有bug。总之,问题似乎解决了。

最新更新