Yii Framework Forum: HAS_ONE отношения, добавление данных - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

HAS_ONE отношения, добавление данных Rate Topic: -----

#1 User is offline   Dima 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 8
  • Joined: 10-January 10
  • Location:Russia, Voronezh

Posted 12 February 2010 - 04:52 PM

Решил сделать свой первый проект с помощью Yii и столкнулся со сложностью.

Есть таблица вида

item
-----
id
user_id
city_id
...
status

в которой хранятся общие сведения об объявлениях (недвижимость).

И есть таблица с подробной информацией о каждом объявлении

item_flat
-----
id
area_kitchen
floor
floor_max
...

id в первой и во второй таблице соответственно ключи.

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

Собственно теперь вопрос: как реализовать все через 1 класс наиболее грамотно с использованием AR?
И правильно ли я подошел к вопросу проектирования БД?

Очень надеюсь на вашу помощь, заранее спасибо.
0

#2 User is offline   creocoder 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 204
  • Joined: 09-March 09
  • Location:*.php

Posted 13 February 2010 - 01:03 PM

1) Реализовать можно при помощи 2 моделей: Item и ItemFlat. Вставка данных транзакциями.

Quote

для коммерческой недвижимости эти поля неактуальны... правильно ли я подошел к вопросу проектирования БД

Первая фраза из цитаты очень говорящая. Из этого вытекает, что не правильно. Я бы использовал паттерн EAV в данном случае, либо если видов объектов недвижимости не так много и их атрибуты заранее известны, то по таблице на каждую сущность.
No good, no bad, only consequence.
0

#3 User is offline   Dima 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 8
  • Joined: 10-January 10
  • Location:Russia, Voronezh

Posted 13 February 2010 - 07:32 PM

creocoder, что-то я не очень понял что не так в цитате. Для коммерческой недвижимости эта информация неактуальна (площадь кухни и т.д.), поэтому будет создана еще 1 таблица со своими специфичными полями. Например, если объявление о продаже/покупке гаража, то необходимо отметить наличие погреба, количество машин, наличие ямы ну и т.д. Соответственно для гаража таблица будет иметь вид

item_garage
----
id
number_of_cars
cellar
...

И класс соответственно ItemGarage.

Quote

1) Реализовать можно при помощи 2 моделей: Item и ItemFlat. Вставка данных транзакциями.

Ну в принципе я так и думал делать. Только через третий класс, который будет полностью отвечать за объект недвижимости (квартира или гараж), скрывая особенности хранения в БД. Вопрос именно в том, как это правильно сделать? Т.е. можно ли использовать возможности AR и отношение типа HAS_ONE, чтобы не писать свой класс. Ведь реализовывать придется те же функции (save(), delete() и т.д.), костыль какой-то получается.

Quote

...то по таблице на каждую сущность.

Вот это в принципе я и хочу реализовать, только чтобы не хранить общую для всех объявлений информацию (дата создания, id пользователя...) я разбил таблицы на общую (items) часть и специфичные (item_flat, item_garage).

С EAV не знаком, спасибо, почитаю.

Большое спасибо за отклик, очень надеюсь на помощь.
0

#4 User is offline   andy_s 

  • Random Member Title
  • Yii
  • Group: Moderators
  • Posts: 1,526
  • Joined: 22-June 09
  • Location:Russia, Kostroma

Posted 14 February 2010 - 03:00 AM

Мне кажется, что EAV здесь - это перебор :)
Идея с хранением общей информации в одной таблице, а в других - только данных, относящихся к конкретному типу объявления, кажется мне хорошей. Да и с помощью Active Record это реализовать не сложно. Создаете классы ItemFlat, ItemGarage с realtions:

'item' => array(HAS_ONE, 'Item', 'id')

Затем можно будет извлечь квартиры вот так:

$flats = ItemFlat::model()->with('item')->findAll()


В обратную сторону уже сложнее, т.к. заранее неизвестно, с какой таблицей нужно будет соединять таблицу Item, и в realtions() уже так явно не задать отношение...

Меня этот вопрос тоже интересует, т.к. я не хочу создавать классы под каждый тип Item, а хотелось бы использовать только один Active Record класс Item. Пока вариант в голову приходит такой: завести поле (напр. $content) в классе Item, в которое при извлечении айтемов ложить всё, что не входит в мета данные таблицы Item. А такие данные появятся, если в передаваемых методам поиска find критериях указывать join = 'INNER JOIN `ItemFlat` ON `t`.`id` = `ItemFlat`.`id`'. В итоге обратиться к информации айтема можно будет например вот так: $item->content['floor'].

Другие интересные идеи приветствуются :)
0

#5 User is offline   Dima 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 8
  • Joined: 10-January 10
  • Location:Russia, Voronezh

Posted 14 February 2010 - 07:08 AM

andy_s, при поиске может и не сложно это сделать, но с добавлением все вовсе не так однозначно. Как с помощью AR можно используя 1 конструкцию save() создать сразу 2 записи в разных таблицах (items и item_garage например)?

И по хорошему, так как ItemGarage вполне самодостаточный объект, внутренняя реализация должна быть скрыта. Т.е. для внешнего пользователя класса должно казаться, что все данные хранятся в одной таблице. И соответственно операции типа
$garage = new ItemGarage;

$garage->user_id = ...;
$garage->number_of_cars = ...;

должны быть доступны напрямую, а не через дополнительные конструкции типа
$garage->items->user_id = ...;

или в любом другом виде. Т.е. хотелось бы иметь для внешнего пользователя наиболее простой интерфейс для работы.

А где хранить правила валидации, если не создавать отдельно классы? Может глуплю, просто еще совсем молод и зелен :rolleyes:
0

#6 User is offline   andy_s 

  • Random Member Title
  • Yii
  • Group: Moderators
  • Posts: 1,526
  • Joined: 22-June 09
  • Location:Russia, Kostroma

Posted 14 February 2010 - 08:10 AM

Quote

Как с помощью AR можно используя 1 конструкцию save() создать сразу 2 записи в разных таблицах (items и item_garage например)?

Либо перегрузить save(), либо использовать beforeSave() для вставки данных в таблицу Item. Дело техники.

Quote

Т.е. хотелось бы иметь для внешнего пользователя наиболее простой интерфейс для работы.

Перегрузить метод __get($name) примерно так:

if ($this->item->hasAttribute($name))
    return $this->item->getAttribute($name);
else
    return parent::__get($name);


Правила валидации в вашем случае хранить, естесственно, в созданном классе :) А вот в задаче, которую описал я, хранить их надо не иначе как в бд.

В общем, идея проста - создать класс (напр. ItemContent), где добавить нужный функционал, а от него уже наследовать ItemGarage, ItemFlat и т.д.
1

#7 User is offline   Dima 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 8
  • Joined: 10-January 10
  • Location:Russia, Voronezh

Posted 14 February 2010 - 08:17 AM

andy_s, спасибо за консультацию. Я в принципе так и думал делать, просто надеялся, что готовое решение есть в Yii :).
0

#8 User is offline   ~CODER~ 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 4
  • Joined: 22-February 10

Posted 22 February 2010 - 02:23 AM

Пока только присматриваюсь к Yii.

В общем смысле я практикую следующий подход: все, что можно - хранится по отдельным справочникам. Справочники могут быть вложенными, как, например Country->State->City. Как правило справочники пополняемые, т.е. в процессе эксплуатации приложения в них добавляются данные. Отдельно стоит вопрос по правам редактирования/удаления данных, а так же доверия введенным данным.

При внесении/редактировании данных в таблицах, использующих справочники, последние выглядят как Select'ы, и, где надо, рядом кнопочка [+].

Голубая мечта - написать автоматический генератор интерфейсов к БД. Что-то подобное я делал много лет назад на Clipper. Достаточно было описать структуру данных таблицы и структуры/правила активных представлений (аналог формы), и на базе этих описаний движок автоматом генерировал весь интерфейс. Дело оставалось за выборками.

Так же и тут. Предлагаю все, что может быть потенциально использовано более чем в одном месте (одной записи) - выносить в справочники. Это обычная практика при нормализации баз данных.
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users