1

SoftDeleteableが Doctrine Extension である ことは誰もが知っています。

これにより、オブジェクトを "ソフト削除" する動作が可能になり、SELECT 時にタイムスタンプを付けてそれらをフィルタリングできますが、データベースから明示的に削除することはできません。

これを考慮して、テーブルに新しい行を挿入し、上記の削除済みとしてマークされているが物理的にそこにある場合の一貫したロジックはどれですか?

ポイントは、私は最近、アプリケーションでこの動作を使用することを余儀なくされたということですが、新しいレコードを挿入しているとき、論理的には、レコードが存在する場合、次のようなエラーが発生しました。

「INSERT INTO fos_user (username, username_canonical, email, email_canonical, enabled, salt, password, last_login, locked, expired, expires_at, Confirmation_token, password_requested_at, roles, credentials_expired, credentials_expire_at, deletedAt, createdAt, updatedAt) VALUES ( ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) ' with params ["admin1" "admin1" "admin "、"管理者"、1、"8ycal2x0eewwg0gw0o0gcw884ooossg"、"886mLvLTi1yPdSBTR9Cfi + + a3lvideQ4pw89ZHDOWVz86kJqXjx7C11ZIwTvzET7N1Fk \ / yHsw10z3Cjm9k + m \ / g =="、null、'0、null、: 2 0; s: 16: \ "ROLE_PROFILE_ONE \" i: 1, s: 16: \ "ROLE_PROFILE_TWO \";} ", 0, null, null," 09/12/2014 18:16:01 ""9/12 /2014 18:16:01"]:

SQLSTATE [23000]: 整合性制約違反: 1062 キー 'UNIQ_957A647992FC23A8' のエントリ 'admin1' が重複しています

私の質問は、SoftdDeleteableを処理して新しいレコードを入力する方法です。あなたが何をするか、またはより少ないアイデアの例が私によく来て、助けになるでしょう.

4

1 に答える 1

2

オリジナルを保持したい場合は、一意のフィールドが以前に使用されていないことを確認する方法を見つける必要があります。これを行う最も簡単な方法は、ユーザー フィールドにカスタム リポジトリを使用し、検索の前に softdeleteable フィルターを無効にすることだと思います。

デフォルトでは、 UniqueEntity は findBy とクラスに設定されたリポジトリを使用しますが、通常のメソッドをそのまま残しながら制約をいじる必要がないように、デフォルトでフィルターを無効にして独自のメソッドを作成することは理にかなっています。

FOSUserBundle を使用しているため (またはテーブル名からそう思われるfos_user)、マッピングに repositoryClass を設定できます (XML は非常に複雑ですが、ここで確認できます)...

// Annotation
@ORM\Entity(repositoryClass="Acme\StoreBundle\Entity\ProductRepository")

//YAML
Acme\UserBundle\Entity\User:
    type: entity
    repositoryClass: Acme\UserBundle\Entity\UserRepository

そして、UserRepositoryあなたのメソッドを追加するだけでfindIncludingSoftdeletedBy、softdeleteableフィルターを無効にします...

namespace Acme\UserBundle\Entity;

use Doctrine\ORM\EntityRepository;

class UserRepository extends EntityRepository
{
    /**
     * Finds users by a set of criteria including sofdeleted.
     *
     * @param array      $criteria
     * @param array|null $orderBy
     * @param int|null   $limit
     * @param int|null   $offset
     *
     * @return array The objects.
     */
    public function findIncludingSoftdeletedBy(
        array $criteria, array $orderBy = null, $limit = null, $offset = null
    )
    {
        // Get array of enabled filters
        $enabledFilters = $this->em->getFilters()->getEnabledFilters();

        // If softdeleteable (or soft-deleteable depending on config) 
        // is in array of enabled filters disable it
        if (array_key_exists('softdeleteable', $endabledFilters)) {
            // disabled softdeleteable filter ($this->em being entity manager)
            $this->_em->getFilters()->disable('softdeleteable');
        }

        // return regular "findBy" including softdeleted users
        return $this->findBy($criteria, $orderBy, $limit, $offset);
    }
}

アップデート

このビットを忘れていました。

次に、この新しい検証制約を参照する独自の検証ファイルを作成する必要があります。(FOSUserBundle と YAML の場合 (私は YAML の方が好きです。XML は画面上で物理学の本が病気になっているように見えます))。

Acme\UserBundle\Entity\User:
    constraints:
        - Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity:
            fields: usernameCanonical
            errorPath: username
            message: fos_user.username.already_used
            // Your method instead of the default "findBy"
            method: findIncludingSoftdeletedBy
            groups: [ Registration, Profile ]
        - Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity:
            fields: emailCanonical
            errorPath: email
            message: fos_user.email.already_used
            // Your method instead of the default "findBy"
            method: findIncludingSoftdeletedBy
            groups: [ Registration, Profile ]

UniqueEntity 制約の詳細については、具体的にはドキュメントを参照してください。

フィールド
タイプ: 配列 | 文字列 [デフォルト オプション]

この必須オプションは、このエンティティが一意である必要があるフィールド (またはフィールドのリスト) です。たとえば、1 つの UniqueEntity 制約で電子メール フィールドと名前フィールドの両方を指定した場合、組み合わせ値が一意であることが強制されます (たとえば、2 人のユーザーが同じ名前を持っていない限り、同じ電子メール アドレスを持つことができます)。 )。

2 つのフィールドを個別に一意にする必要がある場合 (たとえば、一意の電子メールと一意のユーザー名)、2 つの UniqueEntity エントリを使用し、それぞれに 1 つのフィールドを指定します。

于 2014-09-17T11:23:57.683 に答える