当更新父级时,活动记录update_attribute对对象(父级)的关联对象(子级)执行DELETE查询

时间:2012-06-12 13:44:43

标签: ruby-on-rails-3 activerecord

Rails:3.0.11

Ruby:1.9.3

当我更新父对象时,为什么活动记录update_attribute对对象(父对象)的关联对象(子对象)执行DELETE查询?

以下是我的课程:

class User < ActiveRecord::Base

  has_many :user_keywords, :dependent => :destroy  
  has_many :keywords, :through => :user_keywords

end

class UserKeyword < ActiveRecord::Base
  belongs_to :user
  belongs_to :keyword
end

class Keyword < ActiveRecord::Base
  has_many :user_keywords
  has_many :users, :through => :user_keywords
end

在前端,每​​个关键字都有一个复选框。

  • 复选框:关键字1
  • 复选框:关键字2
  • 复选框:关键字3
  • 复选框:关键字4

我第一次选中“关键字1”和“关键字2”复选框来更新用户的关键字。

我再次编辑用户通过选中“关键字1”和“关键字3”复选框更新关联的关键字并更新用户。 第二次更新删除了我的USER_KEYWORDS表中的先前记录。

以下是我的控制台输出,显示正在执行的DELETE语句:

  User Load (55.5ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 5 LIMIT 1
  Keyword Load (0.2ms)  SELECT "keywords".* FROM "keywords" WHERE "keywords"."id" IN (1, 3)
  Keyword Load (0.2ms)  SELECT "keywords".* FROM "keywords" INNER JOIN "user_keywords" ON "keywords".id = "user_keywords".keyword_id WHERE (("user_keywords".user_id = 5))
  AREL (0.2ms)  DELETE FROM "user_keywords" WHERE "user_keywords"."user_id" = 5 AND "user_keywords"."keyword_id" = 2
  AREL (0.1ms)  INSERT INTO "user_keywords" ("keyword_id", "user_id", "status", "created_at", "updated_at") VALUES (3, 5, 'f', '2012-06-12 13:15:43.912236', '2012-06-12 13:15:43.912236')

has_many方法的:dependent选项说(http://guides.rubyonrails.org/association_basics.html#has_many-association-reference):

4.3.2.6:依赖

如果将:dependent选项设置为:destroy,则删除此对象将调用关联对象上的destroy方法以删除这些对象。如果将:dependent选项设置为:delete_all,则删除此对象将删除关联的对象而不调用其destroy方法。如果将:dependent选项设置为:nullify,则删除此对象会将关联对象中的外键设置为NULL。

在关联上使用:through选项时,将忽略此选项。 ##

我无法理解这种行为。任何人都可以详细说明或澄清一下吗?

1 个答案:

答案 0 :(得分:3)

delete语句仅删除了关键字2的关联。当您提交了选中了两个复选框的表单时,系统会假定您希望这两个项目关联,但没有其他项目未检查。因此,当它加载当前的user_keyword关联时,它看到有一个您没有选择保留的现有记录,因此将其删除。然后它看到有一个新的,所以它创建了一个新的。

如果你只想添加关系,而不是删除关系,那么我不推荐复选框,因为选中复选框意味着添加,但删除支票意味着破坏关系(这是rails在这种情况下所做的)。具有AJAX功能的按钮可能更有意义。如果你确实想要保留复选框,但不允许rails来破坏未被选中的关系,那么你必须根据参数自己建立关系,而不是依靠rails magic来为你完成这项工作。< / p>

请注意,这与:dependent选项无关,这仅仅是由于您在模型和表单中设置的关系。