每个人都知道SoftDeleteable是一个学说延伸:
允许行为“软删除”对象,过滤它们 通过使用时间戳标记它们来选择时间,但不是显式 将它们从数据库中删除。
现在考虑到这一点,在表中插入新行并将上面标记为已删除但实际存在时,这将是一致的逻辑吗?
关键是我最近被迫在应用程序中使用这种行为,但是当我插入新记录时,逻辑上,当存在时,我得到了这样的错误:
执行“INSERT INTO fos_user(用户名, 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 (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)'与params [“admin1” “admin1”“admin”,“admin”,1,“8ycal2x0eewwg0gw0o0gcw884ooossg”, “886mLvLTi1yPdSBTR9Cfi + + a3lvideQ4pw89ZHDOWVz86kJqXjx7C1 1ZIwTvzET7N1Fk \ / yHsw10z3Cjm9k + m \ / g ==“,null,0,0,null, null,null,'a:2:{i: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重复条目 'admin1'用于键'UNIQ_957A647992FC23A8'
我的问题是,你如何处理 SoftdDeleteable 来输入新记录?一个例子,你的工作或更少的想法会很好地来到我身边,并会有所帮助。
答案 0 :(得分:2)
如果你想保留原版,那么你需要找到一些方法来确保以前没有使用过这个独特的领域。我认为最简单的方法是为您的用户字段使用自定义存储库,并在搜索之前禁用软删除过滤器。
默认情况下,UniqueEntity使用findBy和类的存储库集,但默认情况下禁用过滤器来创建自己的方法是有意义的,以避免在保持常规方法不变的情况下使用约束。
当您使用FOSUserBundle时(或者从表名fos_user
看来似乎如此),您可以在映射中设置repositoryClass(XML是一大堆混乱,但您可以看到它here )...
// Annotation
@ORM\Entity(repositoryClass="Acme\StoreBundle\Entity\ProductRepository")
//YAML
Acme\UserBundle\Entity\User:
type: entity
repositoryClass: Acme\UserBundle\Entity\UserRepository
然后在您的UserRepository
中添加findIncludingSoftdeletedBy
方法,禁用软删除过滤器,如...
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约束的更多信息,请参阅docs,具体为..
的字段强>
类型:数组| string [默认选项]
此必填选项是此实体应该唯一的字段(或字段列表)。例如,如果您在单个UniqueEntity约束中同时指定了电子邮件和名称字段,那么它将强制使用唯一的组合值(例如,两个用户可以拥有相同的电子邮件,只要他们不具有相同的也是)。
如果您需要要求两个字段单独使用(例如,唯一的电子邮件和唯一的用户名),则使用两个UniqueEntity条目,每个条目都包含一个字段。