У меня есть User
-Entity с самой базовой информацией. User
должен иметь возможность делиться более подробными данными в профиле. Для разных User
существуют разные ProfileSet
.
В этом примере я стараюсь, чтобы это было просто: ProfileSet_A
- это профиль с личной информацией, ProfileSet_B
хранит анонимные данные.
User
может иметь только один ProfileSet
.
Объекты (псевдокод)
// table: users
class User {
protected $id,
$email,
$username,
$password; // ...
}
// table: - none -
class ProfileSet {
protected $id,
$name; // ...
}
// table: profileset_a
class ProfileSet_A extends ProfileSet {
protected $firstname,
$lastname,
$morePrivateStuff; // ...
}
// table: profileset_b
class ProfileSet_B extends ProfileSet {
protected $anyAnonymousStuff; // ...
}
// table: user_has_profileset
class UserHasProfileSet {
protected $user, // relation to User
$profileSet; // relation to ProfileSet_A OR ProfileSet_B
}
Форма, ProfileSet_A
username: [ textfield ]
email: [ textfield ]
firstname: [ textfield ]
lastname: [ textfield ]
morePrivateStuff: [ textfield ]
Форма, ProfileSet_B
username: [ textfield ]
email: [ textfield ]
anyAnonymousStuff: [ textfield ]
Проблемы
UserHasProfileSet
должен относиться к User $user
и ProfileSet
, который может быть экземпляром ProfileSet_A
или ProfileSet_B
. Я хотел бы иметь только поле $profileSet
вместо $profileSet_A
, $profileSet_B
,...
Я хотел бы отредактировать User
и его ProfileSet
(A или B) в той же форме.
Вопрос
Как решить проблемы чистым способом? Я открыт для лучших альтернатив. Может, я ошибаюсь.
Заранее спасибо!
Если вы используете Doctrine
в своем проекте, вы можете архивировать это с наследованием Doctrine, например с MappedSuperClass
:
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="users")
*/
class User
{
// other fields
/**
* @ORM\OneToOne(targetEntity="ProfileSet")
*/
private $profile;
}
/**
* @ORM\Entity
* @ORM\InheritanceType("JOINED")
* @ORM\DiscriminatorColumn(name="type", type="string")
* @ORM\DiscriminatorMap({"a" = "ProfileSet_A", "b" = "ProfileSet_B"})
* @ORM\Table(name="profile_sets")
*/
class ProfileSet
{
// common properties
}
/**
* @ORM\Entity
* @ORM\Table(name="profile_sets_a")
*/
class ProfileSetA extends ProfileSet
{
// ...
}
/**
* @ORM\Entity
* @ORM\Table(name="profile_sets_b")
*/
class ProfileSetB extends ProfileSet
{
// ...
}
В этом случае Doctrine создаст 3 таблицы: profile_sets
которые будут содержать общие поля, а тип профиля, profile_sets_a
и profile_sets_b
будут содержать определенные поля. Когда вы получаете Свойство User
с $profile
, Doctrine автоматически сопоставляет необходимый объект.
Поскольку у вас есть только одна запись ProfileSet
для каждого User
нет необходимости определять дополнительный UserHasProfileSet
и вы можете просто установить связь OneToOne
напрямую. Но вы можете сделать это так же, как вам нужно.
Doctrine
?