2016-12-05 4 views
-1

Я только начал изучать cakePHP несколько дней назад, и это меня смущает. Если бы я написал проект с нуля, моя система позволила бы сказать, что пользователи и каждый пользователь будут иметь один профиль. Поэтому я бы создал таблицы базы данных следующим образом:Является ли моя база данных и понимание структуры неправильным?

+----+----------+----------+------------+ 
| id | username | password | profile_id | 
+----+----------+----------+------------+ 
| 1 | ksno  | ksno  |   1 | 
| 2 | cake  | bake  |   2 | 
+----+----------+----------+------------+ 

+----+-----------+----------+---------------+ 
| id | firstname | lastname | birthday | 
+----+-----------+----------+---------------+ 
| 1 | Alex  |   | in few months | 
| 2 | cake  | PHP  |    | 
+----+-----------+----------+---------------+ 

И тогда я мог бы создать объект профиля от пользователя. Проблема в том, что мне нужно сначала создать профиль, потому что пользователи таблицы имеют внешний ключ профиля. Хорошо, я бы просто начал транзакцию и совершил после того, как все было успешно создано. Вот как я узнал его ...

Но если я взгляну на cakePHP docs and book:

Если таблица содержит внешний ключ, он принадлежит к другой таблице.

Так что в основном означает ... Пользователь относится к профилю? Но это не так. Я почти закончил свои действия с CRUD на пользователе и его профиле ... Но я чувствую, что делаю что-то неправильно ... После книги ... Мы могли бы сохранить сущность и ее ассоциации из формы следующим образом:

$entity = $users->newEntity($this->request->data(), [ 
    'associated' => [ 
     'Profiles' => ['validate' => false], 
    ] 
]); 

Но это требует, чтобы изменить схему базы данных, которая привела бы меня неправильно понять, что происходит, потому что я наклоняю первый сохранить пользователь без идентификатора профиля ... Так что я пошел и сделал это:

$userProfilesRepository = TableRegistry::get('UserProfiles'); 
$userProfile = $userProfilesRepository->newEntity(); 
$userProfile = $userProfilesRepository->patchEntity($userInfo, $this->request->data); 
$user = $this->Users->patchEntity($user, $this->request->data); 
if ($userProfilesRepository->save($userInfo) && $this->Users->save($user->set('profile_id', $userInfo->get('id')))) {... 

Может кто-нибудь, пожалуйста, помогите указать мне правильный способ мышления о схемах баз данных и ассоциациях каркасов? Я чувствую, что делаю неправильно, но только потому, что я борется с CakePHP.

+0

Ваши таблицы являются разумными. Такие платформы, как CakePHP и другие, которые используют объектно-реляционные карты, заставляют вас использовать модель сетевых данных, наивное и ограниченное мышление, которое возвращается к предреляционным дням. Многие из того, что можно сделать в SQL, не поддерживаются такими структурами. Я предлагаю вам изучить разные модели данных (сеть, сущность-отношения и реляционные отношения), поскольку знание их ограничений и способность переводить между ними должны прояснить многие проблемы, с которыми вы сталкиваетесь. – reaanb

+0

Являются ли такие рамки изменением моего рабочего процесса разработки каким-то образом? Сначала я создал ER-модели, а затем основал их, создал мою базу данных, а затем начал изучать cakePHP и писать свое приложение. Но тогда дело доходит до этого момента, когда я чувствую себя неправым и думающим: с чего начать? Или я должен просто перепроектировать мою базу данных так, чтобы она была совместима с каркасом? – ksno

+0

Я давно решил отказаться от объектно-реляционных карт (и фреймворков, которые зависят от них). Моделирование данных и системное моделирование являются отдельными дисциплинами. Я делаю классы для системных обязанностей и обрабатываю данные в наборах, поэтому у меня нет ограничений на то, как я моделирую свои данные. К сожалению, я не могу помочь вам работать в рамках. – reaanb

ответ

0

Я думаю, что у вас есть отношение назад. Вы не должны иметь поля profile_id в таблице users; вы должны иметь поле user_id в таблице profiles. Затем профиль «принадлежит» пользователю, что, вероятно, имеет для вас больше смысла.

+0

Это может быть правдой, но позволяет использовать профиль userOne, а не профиль «принадлежит пользователю». Почему я должен сохранять FK в таблице профилей, если у пользователя есть профиль, пользователь должен знать, какой профиль у него есть, но не профиль должен знать, от какого пользователя это зависит ... Что делать, если я хочу создать профиль без пользователя? Но все равно будет заставлять каждого пользователя иметь профиль. Это то, что меня смущает. – ksno

+0

Высказывание пользователя 'hasOne' и профиля' ownTo' являются теми же, что касается Cake; это та же структура базы данных, которая просматривается с двух сторон. Вы можете создать профиль без пользователя, просто используя 'user_id' null в таблице профилей. –

+0

@ksno «пользователь должен знать, какой профиль у него есть» - это ложное рассуждение. * Пользователь dabase * должен знать. Соответствующими отношениями приложения являются: «ИД пользователя имеет имя« ИМЯ »и« ПАРОЛЬ ПАРОЛЯ »,« Идентификатор профиля имеет настоящее имя FIRSTNAME LASTNAME и дату рождения BIRTHDATE »и« пользователь USER_ID имеет профиль PROFILE_ID ». Вы можете легко совместить последние два с таблицей «Идентификатор профиля имеет настоящее имя FIRSTNAME LASTNAME и дату рождения BIRTHDATE», а пользователь USER_ID имеет идентификатор профиля ». Но объединение первых двух дает сложное значение, включающее NULL, и требует более сложного ограничения, чем просто FK. – philipxy

0

Вы просто должны сохранить профиль пользователя и связать пользователя с ним

$userProfilesRepository = TableRegistry::get('Profiles'); 

    $data = [ 
     'firstname' => 'FOO', 
     'lastname' => 'BAR', 
     'user' => [ 
      'username'=>'foo', 
      'password'=>'bar' 
     ] 
    ]; // Dummy data 

$entity = $userProfilesRepository->newEntity($data, [ 
    'associated' => [ 
     'Users' => ['validate' => false], 
    ] 
]); 

Это создаст профиль пользователя, а затем сохраните ассоциацию. Надеюсь, это очистит его.

0

ORM являются проблематичными и не получают реляционной модели. Тем не менее: создайте свою базу данных, затем опишите через ORM «отношения» [sic]. «Принадлежит к» - это просто название декларации. Этот выбор имени вдохновлен ситутатоном, где слабый тип сущности ER (возможно, ассоциативный) имеет FK в PK для PK другого типа «владеющего» типа, к которому он «принадлежит». Просто используйте объявления, которые помещают FK, где вы хотите их. Не волнуйся о написании.

(Вы можете думать о некоторых декларациях записи/модели в описании вычисляемых столбцов для соответствующей таблицы, которые являются только в схеме в другой таблице.)

Re дизайна: Насколько ER является concered, пользователи, имеющие необязательные профили предполагают прямую схему, в которой профили являются слабыми объектами с FK для пользователей, к которым они принадлежат. Но вы думаете о том, что у пользователей есть профиль FK, для которого также потребуется ограничение . Каждый профиль отображается как FK ровно одному пользователю.Это излишне сложный дизайн. Простая конструкция заключается в том, чтобы поместить FK в таблицу профилей, что согласуется с тем, что «профиль принадлежит пользователю».