Active record update_attribute executes a DELETE query on an associated object(child) of an object(parent) when parent is updated

不打扰是莪最后的温柔 提交于 2019-12-07 21:42:52

问题


Rails: 3.0.11

Ruby: 1.9.3

Why does active record update_attribute executes a DELETE query on an associated object(child) of an object(parent) when I updated the parent?

Following are my classes:

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

On front-end I have a checkbox for each keyword.

  • Checkbox: Keyword 1
  • Checkbox: Keyword 2
  • Checkbox: Keyword 3
  • Checkbox: Keyword 4

First time I checked "Keyword 1" and "Keyword 2" checkboxes to update the user's keywords.

I again edited the user to update the associated keywords by checking "Keyword 1" and "Keyword 3" checkboxes and updated the user. The second updated deleted the previous records in my USER_KEYWORDS table.

Following is my console output showing the DELETE statement being executed:

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

The :dependent option on has_many method says (http://guides.rubyonrails.org/association_basics.html#has_many-association-reference):

4.3.2.6 :dependent

If you set the :dependent option to :destroy, then deleting this object will call the destroy method on the associated objects to delete those objects. If you set the :dependent option to :delete_all, then deleting this object will delete the associated objects without calling their destroy method. If you set the :dependent option to :nullify, then deleting this object will set the foreign key in the associated objects to NULL.

This option is ignored when you use the :through option on the association. ##

I am unable to understand this behavior.Can anybody please elaborate or clarify in this?


回答1:


The delete statement only deleted the the association for keyword 2. When you submitted the form with two checkboxes checked, the system assumes that you want those two items associated, but none of the others that were not checked. Therefore, when it loaded the current user_keyword associations, it saw that there was one existing record that you did not choose to keep, so it deleted it. It then saw that there was one new one, so it created a new one.

If you want to only add relationships, and not remove relationships, then I would not recommend checkboxes, as checking a checkbox implies adding, but removing a check implies destroying the relationship (which is what rails did in this case). A button with AJAX functionality might make more sense. If you do want to keep checkboxes, but not allow rails to destroy relationships that weren't selected, then you would have to build the relationships yourself based on the parameters, and not rely on the rails magic to do the job for you.

Note that this is not related to the :dependent option, this is simply due to the relationship you have set up in the models and in the form.



来源:https://stackoverflow.com/questions/10997990/active-record-update-attribute-executes-a-delete-query-on-an-associated-objectc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!