Новости Joomla

0 Пользователей и 1 Гость просматривают эту тему.
  • 6 Ответов
  • 5290 Просмотров
*

Extalionez

  • Осваиваюсь на форуме
  • 36
  • 5 / 0
Доброго времени суток, уважаемые профессионалы! Столкнулся с одной проблемой при написании расширения для Joomla 2.5. А именно - структура таблиц моей базы данных состоит из 3-й нормальной формы. В результате чего, при добавлении/редактировании материала мне необходимо работать одновременно с несколькими таблицами. Но как я уяснил отсюда http://docs.joomla.org/Developing_a_Model-View-Controller_Component/2.5/Adding_backend_actions существует возможность редактировать одновременно только одну таблицу в базе данных, что естественно меня не устраивает. Вот и пришёл к Вам на поклонение за помощью ^-^
*

rsa_m

  • Захожу иногда
  • 254
  • 22 / 0
Если 3НФ, то таблицы связанные.
Можно решить проблему в обход, редактируя каждую из таблиц в своей форме. Затем выведя эти формы в один темплей как layout (закладки).

Если же нужно именно на на одной странице tmpl выводить все связанные таблицы и редактировать их, то пока у меня ответа нет. Но тоже озадачен этим вопросом. Есть идеи. Проверю - отпишу.
*

rsa_m

  • Захожу иногда
  • 254
  • 22 / 0
Проведя изыскания по теме, пришел отчасти к философским выводам.
Прошу прощения за "лекцию" ниже. Кому интересно только решение - читайте начиная со строки **************************

Таблицы мы приводим к НФ именно для того чтобы устранить возможные коллизии, а все остальное - вторично. Поэтому мешать в одну кучу несколько таблиц может быть чревато, а в некоторых случаях доводит до того что нам нужна не 3я, а 1я нормальная форма для реализации задуманного.

Проще объяснить на примере:
У нас есть 4ре таблицы. Запишу в виде Название_таблицы(названия_полей)

Город(id_города; название_города)
Улица(id_улицы; названия_улицы)
Адрес(id_адреса; id_города; id_улицы; номер_дома; номер_квартиры)
Собственник(id_собственника; id_адреса; ФИО)

Т.е. по связи таблиц получаем цепочку: Город/Улицы -> Адрес -> Собственник
Причем заметим что таблицы Город и Улицы друг с другом напрямую не связаны.

Такую форму мы делаем для того чтобы делать исправления улицы или города только в  одном единственном месте, а не в 100 или 1000 местах если бы у нас была только одна таблица и оказалось бы что какое либо название города нудно исправить.

Вывести все таблицы по отдельности на одну страницу проблем не составляет.
Но тут возникает первое философское отступление:
- для нас как для пользователя интересна не каждая таблица в отдельности, а результирующая таблица: Информация_о_собственнике(Город, Улица, Номер_дома, номер_квартиры, ФИО).
- но как для человека который будет вносить данные в эти таблицы, интересны именно отдельные таблицы.

Теперь о главном.
Что значит "редактировать материал на одной странице" !?

Из приведенного примера видно, что редактировать на одной странице таблицы Город и Улица теоретически можно, потому что эти таблицы не связаны. И для нас как для пользователя понятно что мы можем менять названия в ячейках этих таблиц произвольно и независимо друг от друга.
Но как это Вы представляете себе в реальности.
Для того чтобы редактировать запись в таблице, необходимо выбрать какую конкретно запись мы хотим редактировать. Если мы выберем конкретную запись из таблицы Город, то таблица Улица здесь уже не к месту будет.
Т.е. прихожу к выводу что в этом случае редактировать нужно одну таблицу, а не две или больше.

Таблица Собственник - другое дело. Тут можно предположить что при выводе этой таблицы и выборе конкретной ее записи для редактирования нам должна открываться форма редактирования в которой помимо поля ФИО, вместо поля id_адреса нам выводились бы отдельно Город, Улица, Номер_дома. И каждое из этих полей мы бы тоже могли редактировать прямо в этой единой форме.
И тут возникает второе философское отступление: Но позвольте! Мы выбрали для редактирования конкретную запись таблицы Собственник.
Далее если мы хотим изменить город, заменив его на другой - то это будет означать что мы хотим внести изменения на самом деле в таблицу Адреса. Но кто сказал что в таблице Собственник только одна запись с этим адресом. И если их несколько, то город будет заменен и в других записях, так как изменения коснуться таблицы Адрес.
Будет путаница. Мы вошли в редактирование конкретной записи, а с какого то после ее изменения поменялись данные и у других  :(

Другими словами. Если дому будет присвоен другой номер, то Вы должны зайти в таблицу Адрес и исправить в ней номер дома.
А если собственник стал собственником по другому адресу, то должны зайти в таблицу Собственник и выбрать там другой адрес, предварительно его создав.

Т.е. получаем что не стоит мешать каким либо образом несколько таблиц для редактирования на одну форму. Только путаница будет.

**********************************************************
Как же все же сделать так чтобы можно было сохранить данные в несколько таблиц (для тех кто в танке  ;D). Предположим что таблицы описанные выше: Город, Улица и т.д.

В mycomponent/view/view.hml.php
Код
   function display($tpl = null)
   {
.....
     $this->cityitems = $this->get('CityItems');
     $this->streetitems = $this->get('StreetItems');
.....

В mycomponent/models/myname.php
Код
class TSJModelTSJs extends JModelList
{
   var $_city;
   var $_street;
   var $_address;
....
   function getCityItems()
   {
      // Загружаем данные, если они еще не загружены
      if (empty( $this->_city ))
      {
         $query = 'SELECT * FROM #__my_city ORDER BY city' . ' ' . 'asc';
         $this->_city = $this->_getList( $query );
      }

      return $this->_city;
   }

   function getStreetItems()
   {
      // Загружаем данные, если они еще не загружены
      if (empty( $this->_street ))
      {
         //$orderDir = $this->state->get('list.direction','asc');
         $query = 'SELECT * FROM #__my_street ORDER BY street' . ' ' . 'asc';

         $this->_street = $this->_getList( $query );
      }

      return $this->_street;
   }
.......

Теперь данные из двух таблиц готовы для вывода в форму.
В форме XML myname.xml делаем необходимые нам поля типа:
Код
      <field
         name="city"
         type="City"
         label="city"
         description="city"
         size="1"
         default=""
      />
      <field
         name="street"
         type="Street"
         label="street"
         description="street"
         size="1"
         default=""
      />
Типы полей либо свои делаем либо используем готовые - в зависимости от задачи.


Теперь сохранение данных в несколько таблиц.
Для этого в tables/myname.php (по названию таблицы - проще запомнить так, что файл должен называться так же как и XML файл формы)
переписываем метод store()
class TSJTableAccount extends JTable
{
   var $street_id = null;
   var $street = null;
   var $city_id = null;
   var $city = null;

   function __construct(&$db)
   {
      // В конструкторе действительно можно указать только одну таблицу
      parent::__construct('#_название_таблицы', 'основной_ключ_таблицы', $db);
   }

   // Но кто сказал что данные полученные из формы мы не модем записывать и в другие таблицы
   public function store($updateNulls)
   {
      // В этом месте пишем запись данных в нужные нам таблицы, хоть две, хоть десять.

      // А этот метод нам сохранит данные автоматом в таблицу указанную в конструкторе
      return parent::store($updateNulls);
   }
*

Extalionez

  • Осваиваюсь на форуме
  • 36
  • 5 / 0
Спасибо за интересную статью. Однако тут ещё один наглый вопросик нарисовался - как правильней чекать возможность удаления записи в таблице перед удалением. Ибо эта Joomla не понимает что нельзя удалить связанную запись и выводит тупо fatal error если попытаться удалить такую запись. Ещё раз Спасибо!
*

passer

  • Завсегдатай
  • 1013
  • 75 / 3
Не очень хорошо ориентируюсь в API Joomla. Но думаю что вы ошибаетесь с инструментами. Наследники JTable позволяют работать с одной таблицей и это хорошо, не нужно ничего менять. Действий по изменению таблиц всего три - insert, update, delete. Наверное целесообразней обрабатывать реляционные связи в моделях. Т.е. прописывать методы insert, update, delete  в моделях. И в этих методах вызывать последовательно методы JTable (check, save, store, delete) для нужных таблиц. Тогда в контроллере вызывая метод delete (например) одной модели, будем точно знать, что данные удалятся не только из одной таблицы, но и из других связанных таблиц. Правда целостность данных это обеспечит не в полной мере. По уму лучше сделать таблицы InnoDB, установить связи на уровне БД и написать запросы руками с использованием транзакций. Тогда целостность данных будет обеспечена более гарантированно.
*

rsa_m

  • Захожу иногда
  • 254
  • 22 / 0
Не очень хорошо ориентируюсь в API Joomla. Но думаю что вы ошибаетесь с инструментами..... Наверное целесообразней обрабатывать реляционные связи в моделях.

Да. Согласен. В модели тоже все это можно сделать. Я пробовал и в класс JTable работу с несколькими таблицами вставить и в модели метод save (или store - точно не помню) заменить. Работает и так и так. Но Вы правы. Правильнее сделать в модели.
*

rsa_m

  • Захожу иногда
  • 254
  • 22 / 0
.....как правильней чекать возможность удаления записи в таблице перед удалением. Ибо эта Joomla не понимает что нельзя удалить связанную запись и выводит тупо fatal error если попытаться удалить такую запись....

Как уже написал Passer, для того чтобы таблицы были действительно связанные и работали с внешним ключом необходимо использовать тип InnoDB.
Далее все как обычно для InnoDB. В одной таблице создаете PRIMARY KEY, в другой на связное поле делаете Foreign key. После этого Joomla отлично работает с этими таблицами. При попытке удалить запись из связных полей, если в другой таблице есть связные записи, будет выдана ошибка.

В модели пишите так (например модель для таблицы Город):
Код
class MyModelCity extends JModelAdmin
{
.....
   function delete()
   {
      $cids = JRequest::getVar( 'cid', array(0), 'post', 'array' );
      $row = $this->getTable();

      foreach($cids as $cid) {
         if (!$row->delete( $cid )) {
            $this->setError( $row->getError() );
            return false;
         }
      }
      
      return true;
   }
.....

И получите при удалении нормальное сообщение типа:
"Error: One or More Citys Could not be Deleted"

P.S.: С каскадным удалением к сожалению не работал. Поэтому не могу сказать как его организовать.
« Последнее редактирование: 02.12.2012, 16:19:14 от rsa_m »
Чтобы оставить сообщение,
Вам необходимо Войти или Зарегистрироваться
 

Документация по созданию модуля для Joomla 2.5 и Joomla 3.x

Автор b2z

Ответов: 1
Просмотров: 1992
Последний ответ 29.07.2015, 09:40:30
от b2z
MVC, работа с видами

Автор borodatych

Ответов: 23
Просмотров: 1764
Последний ответ 06.04.2015, 14:53:12
от b2z
JPluginHelper::importPlugin('content') в Joomla 1.7

Автор Dutch

Ответов: 2
Просмотров: 4468
Последний ответ 30.03.2015, 14:22:51
от twins717
Документация по созданию компонента для Joomla 2.5

Автор Sulpher

Ответов: 74
Просмотров: 55379
Последний ответ 17.11.2014, 13:43:07
от limon142
Документация по созданию плагина для Joomla 2.5 и Joomla 3.x

Автор b2z

Ответов: 8
Просмотров: 13445
Последний ответ 27.08.2014, 09:52:02
от skinny