2017-05-17 7 views
0

archived usersと呼ばれるusersのバックアップテーブルを作成しようとしています。現在のユーザー属性(自己)のハッシュを取り、self.idのマージをuser_idとしてArchivedUserを作成します。ArchivedUserのレコードを作成または更新します

ユーザーが復職すると、ArchivedUserというレコードはまだArchivedUserのテーブルに残ります。ユーザーがもう一度削除されると、変更されたすべての属性が更新されます。

は現在、それは検証エラーがスローされます。 Validation failed: User has already been takenself.idはすでにArchivedUserテーブルに存在します。

可能であれば既存のオブジェクトを更新するオブジェクトを処理する、または存在しない場合は新しいレコードを作成するより良い方法はありますか?私はRailsの4を使用していますし、find_or_create_byを試してみましたが、それはその列が両方のテーブルに存在し、変更されませんので、奇数のエラー

Mysql2::Error: Unknown column 'device_details.device_app_version'

をスローします。

ユーザーは、メソッド

# creates ArchivedUser with the exact attributes of the User 
    # object and merges self.id to fill user_id on ArchivedUser 
    if ArchivedUser.create!(
    self.attributes.merge(user_id: self.id) 
) 
のぞき見を取るための

感謝を削除します!

答えて

0

あなたarchived_usersテーブルが本当にユーザーのためのバックアップとして機能し、任意の追加機能を追加していない場合、私はArchiveUserモデルを捨てて、単にユーザーがアーカイブされているかどうかを伝えるためにUserモデルにarchivedブール値を追加します。

このように、オブジェクトを別のテーブルに移動して、削除コールバックにフックする必要はありません。

ただし、ArchiveUserモデルでは、Userとは異なる機能が提供されている場合は、single table inheritenceを使用してユーザーの種類を区別することもできます。この場合、Userはすべてのユーザーを管理し、次にユーザーがActiveUserまたはArchivedUserのように区別することができます。

STIを使用していない場合は、セットアップがより多く必要になりますが、混乱する可能性はありますが、2つの類似したモデルがほんのわずかしか異なる必要がない場合に役立ちます。あなたがからオブジェクトを作成しようとしている場合は


  1. それはあなたがあなたの現在の設定を維持したいならば、私はあなたのコードを参照いくつかの問題があると信じて、言われています既存のオブジェクト、duplicate the object (dup)には良い習慣です。そうすれば、idは自動的には設定されず、自動的にインクリメントされます。

  2. データベースから実際にUserレコードを削除した場合、そのレコードが削除されたため、そのidへの参照を保存する理由はありません。しかし、実際にレコードを削除していない場合は、ブーリアン属性を使用して、ユーザーがアクティブであるかアーカイブされているかどうかを判断する必要があります。

  3. 私はなぜfind_or_create_byが機能していないのかについての文脈が十分ではありませんが、その場合はできるだけ単純にしています。すべての属性を使用するのではなく、あなたが知っている一貫した値(idなど)だけが適切な結果を返します。

  4. if ArchivedUser.create! # ...は問題があります。作成後のバン(すなわち、create!)は、レコードを作成できなかった場合はエラーをスローし、ifを無意味にします。したがって、エラーがスローされないようにして、レコードが作成されていない状態を処理したい場合は、ifを使用してください。または、エラーをスローしたい場合はifなしでcreate!を使用してください。

関連する問題