1

レールで依存モデルを部分的に削除/破棄する方法を見つけようとしています。

コードは次のようになります。

class User < ActiveRecord::Base

  has_many :subscriptions
  has_many :photos, :dependent => :destroy
  has_many :badges, :dependent => :destroy

  before_destroy :partial_destroy

  def partial_destroy
    self.photos.destroy_all
    self.badges.destroy_all
    return false if self.subscriptions.any? 
  end
...

基本的に、写真とバッジを破棄したいのですが、ユーザーがサブスクリプションを持っている場合は、それらを保持し、ユーザーが破棄されないようにしたいと考えています。

.each { |obj| obj.destroy }を使ってみましたが、問題ないようです。deletedelete_all

before_destroyがfalseを返すたびに、レールが何らかのロールバックを実行しているようです。依存関係の一部を破壊する方法はありますか?

4

2 に答える 2

1

私は最終的に次のことをしました:

  • destroyモデルのオーバーライドUser(以下を参照)
  • を実際に削除するのUserではなく、必要のない依存関係を破棄し、Userモデル自体のフィールド (電子メールなど) を空白にします。
  • ユーザーを受け取り、すべてのクリアリング操作を実行するクラスを作成しました。UserDeleterこれは、物事をよりクリーンに保つ/ある種の単一の責任を持つためです

オーバーライドdestroy

  def destroy
    run_callbacks(:destroy) do
      UserDeleter.new(self).delete
    end
  end

依存関係の削除とユーザーのデータの消去

class UserDeleter

  def initialize(user)
    @user = user
  end

  def delete
    delete_photos
    delete_badges
    clear_personal_data
    # ...
  end

  private

  def delete_photos
    @user.photos.destroy_all
  end

  def clear_personal_data
    @user.update_attributes!(
      :email => deleted_email,
      :nickname => '<deleted>')
  end

  def deleted_email
    "deleted@#{random_string}.com"
  end

  def random_string(length = 20)
    SecureRandom.hex(length)[0..length]
  end
#...
end
于 2014-08-30T08:49:50.773 に答える