3

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」のチェックボックスをオンにして、関連するキーワードを更新するようにユーザーを再度編集し、ユーザーを更新しました。2番目の更新により、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オプションを使用する場合、このオプションは無視されます。##

私はこの振る舞いを理解することができませんが、誰かがこれについて詳しく説明したり明確にしたりできますか?

4

1 に答える 1

3

delete ステートメントは、キーワード 2 の関連付けのみを削除しました。2 つのチェックボックスをオンにしてフォームを送信すると、システムは、これら 2 つの項目を関連付けたいと想定しますが、チェックされていない他の項目は関連付けないと想定します。そのため、現在のuser_keyword関連付けをロードしたときに、保持することを選択しなかった既存のレコードが 1 つあることがわかり、それが削除されました。次に、新しいものが 1 つあることがわかったので、新しいものを作成しました。

リレーションシップを追加するだけで、リレーションシップを削除したくない場合は、チェックボックスをオンにすることは追加を意味するため、チェックボックスをお勧めしませんが、チェックを外すとリレーションシップを破棄することを意味します (この場合、レールはこれを行いました)。AJAX 機能を備えたボタンの方が理にかなっています。チェックボックスを保持したいが、レールが選択されていない関係を破棄することを許可しない場合は、パラメーターに基づいて自分で関係を構築する必要があり、レールの魔法に頼って仕事をする必要はありません。

これはオプションとは関係がないことに注意してください:dependent。これは単に、モデルとフォームで設定した関係によるものです。

于 2012-06-12T14:39:47.733 に答える