論理削除を JoinTable する際にも適用する方法について

237 views
Skip to first unread message

yuki

unread,
Apr 15, 2014, 10:24:20 AM4/15/14
to symfony-...@googlegroups.com
Symfony2 勉強中の yuki です。

下記の論理削除を用いた開発でのことで、アドバイスをいただきたいことがあります。


まず前提としまして、下記のようなテーブル構成になっています。

------------------------------------------------------------------

[ user テーブル ]

| id | name
+----+--------
| 5  | 太郎


[ item テーブル ]

| id | name
+----+--------
| 10 | ペン
| 11 | 消しゴム


[ user_item テーブル ]

| id | user_id | item_id | deleted_at
+----+---------+---------+------------
| 1  | 5       | 10      | NULL
| 2  | 5       | 11      | 2014-01-01

------------------------------------------------------------------

User の持ち物 Item の情報を格納しているのが UserItem テーブルです。


User Entity では下記のアノテーションで、Item を join しています。

    /**
     * @ORM\ManyToMany(targetEntity="Item")
     * @ORM\JoinTable(
     *      name="user_item",
     *      joinColumns = { @ORM\JoinColumn(name="user_id", referencedColumnName="id") },
     *      inverseJoinColumns = { @ORM\JoinColumn(name="item_id", referencedColumnName="id") }
     *  )
     */
    protected $items;

通常ですとこれで問題ないのですが、最初に述べた論理削除を使った場合ですと、
SQL クエリに論理削除の処理が加わらず、論理削除したものまですべて取得されてしまいます。

UserItem Entity には @Gedmo\SoftDeleteable(fieldName="deletedAt") を記入しており、
UserItemRepository で UserItem Entity を直接取得する分には論理削除が機能しています。
しかしながら、上述のように join の仲介で使用すると機能しません。

JoinTable の指定でなにか追記しなければならないことなどあるのでしょうか。
原因として考えられることがございましたら、どうかご助言のほどよろしくお願いいたします。

つたない説明で申し訳ありません。
不明瞭なところがありましたら、ご指摘いただければと思います。

hidenorigoto

unread,
Apr 17, 2014, 6:32:32 AM4/17/14
to symfony-...@googlegroups.com
yukiさん

後藤です

ご質問内容の直接的な回答としては「できない」となるのかと思います。


ご存知かもしれませんが念のために書いておくと、ORMのManyToManyは、DBの関連テーブルをプログラム側で意識することなく多対多を扱うための設定です。
この場合、関連テーブルである user_item はプログラム側では直接操作しません。
(ManyToMany の普通の構成では、UserItem エンティティを定義しません)


yuki さんは UserItem を直接操作するために別途エンティティとして定義されているのだと思います。
しかし、User などから ManyToMany をたどる場合は、 UserItem エンティティクラスのメタ情報は参照されないので、SoftDeletable 等も効かないという挙動かと思います。


試していませんが、ManyToMany ではなくて、明示的に UserItem に関連するようにして OneToMany で扱うという方針に変更してみてはどうでしょうか。



(※私個人としては、論理削除のような制約はORMの外で扱うようにしているので、この辺りの突っ込んだ使い方にイマイチ詳しくはありません。詳しい方HELP)

yuki

unread,
Apr 24, 2014, 8:57:32 PM4/24/14
to symfony-...@googlegroups.com
hidenorigoto さん

yukiです。
ご助言ありがとうございます!
ご返信の確認が遅れ申し訳ありませんm(_ _)m

ManyToMany の場合はつなぎの Entity 情報は参照されないのですね…。
アドバイスいただいたように、直接 ManyToMany にはせず ManyToOne - OneToMany でつないだところ、
希望どおり論理削除が動作しました!

コードがややこしくなるので、ManyToMany を使うか、論理削除を使うのをやめるか悩むところです…。

もう少しいろいろやってみて、なにかよい解法が見つかりましたら、また投稿します。
アドバイスありがとうございました!

2014年4月17日木曜日 19時32分32秒 UTC+9 hidenorigoto:
Reply all
Reply to author
Forward
0 new messages