Розглянуто варіант автоматичного підключення класів моделей з вказаній директорії
Mojolicious - фреймворк для написання веб-додатків, що має в своєму арсеналі багато корисного функціоналу як спочатку здається, на всі випадки життя. Але коли починаєш з ним щільно працювати і намагатися написати великі додатки, можна наштовхнутися на ситуацію, коли потрібні рішення відсутні в базовому наборі. Особисто для мене недоліком моджо стало відсутність в ньому моделей. Притому, що дивно, даний функціонал не реалізований ні в самому моджо, ні в плагінах до нього, пошук по CPAN і в Гуглі не виявив відповідних плагінів.
За час роботи з фреймворком Catalyst я звик до MVC. і не хотілося відмовлятися від даного принципу розробки в моджо.
Отже, чого хочеться? Хочеться моделей як в Catalyst, щоб з контролера можна було робити виклики виду:
і щоб фреймворк сам довантажувати всі моделі з відповідною директорії.
У моджо програмісту самому пропонується дописувати необхідний функціонал (наприклад, винести в модулі окремої Директорією), або писати обробку даних і бізнес-логіку прямо в контролерах. Подібний підхід застосовується в веб-фреймворк на інших мовах програмування, наприклад, laravel на php, flask на python і revel на Go.
Реалізація
Отже, для створення моделі робляться такі кроки (покажу на прикладі нового додатка):
- Генерітся mojo-додаток: mojo generate app MyApp cd my_app / lib.
- Створюємо необхідні файли і директорії: touch MyApp / Model.pm mkdir MyApp / Model touch MyApp / Model / Base.pm.
- Правимо MyApp.pm:
У файлі MyApp.pm ми створили об'єкт класу MyApp :: Model. якому в конструктор передали поточний об'єкт. Передача в конструктор поточного об'єкта необхідна для того, щоб потім з моделі можна було звертатися до всіх методів поточного класу.
У MyApp / Model.pm в конструкторі ми знаходимо всі файли в директорії MyApp / Model / використовуючи клас Mojo :: Loader і метод search. Тут необхідно уточнити, що Mojo :: Loader не вміє рекурсивно обходити каталог, тобто якщо директорія MyApp / Model має вигляд:
то Mojo :: Loader-> search ( 'MyApp :: Model') проігнорує директорію MoreModel і завантажить модулі тільки з кореневої директорії. Як варіант, можна додатково в циклі перебрати всі піддиректорії в кореневій директорії і згодувати їх також Mojo :: Loader для завантаження модулів.
Далі за кодом. У конструкторі моделі ми довантажувати кожен знайдений модуль з моделлю (за винятком MyApp :: Model :: Base. Про нього далі) і завантажуємо його в хеш modules. Метод get_model повертає клас, відповідний запитуваній, або падає з помилкою.
У файлі MyApp / Model / Base.pm ми вказуємо всі методи, які будуть успадковуватися іншими моделями. Виходячи з назви стає зрозуміло, що це батьківський клас для інших модулів з моделями. рядок
говорить про те, що необхідно представити елемент об'єкта
як метод класу. Тобто виклик $ self-> app-> config рівносильний $ self -> -> config. Це синтаксичний цукор від творця моджо.
Що таке app можна зрозуміти, поглянувши на код модуля MyApp.pm. Це об'єкт самого верхнього класу MyApp.pm. який ми передали в конструктор.
Тепер наведемо приклад найпростішого модуля з моделлю, наприклад, MyApp / Model / MyModel.pm:
Викликати даний метод з контролера легше легкого:
В даному випадку буде викликаний хелпер model. Певні в методі MyApp :: startup. Даний хелпер поверне виклик методу get_model об'єкта класу MyApp :: Model.
Ну от і все. Як бачите, нічого особливо складного немає. Я сподіваюся, що через некториє час у мене дійдуть руки оформити це все у вигляді плагіна для моджо, так як з ним останнім часом я працюю досить активно, і писати один і той же код постійно стомлює. По крайней мере, проект на гітхабе під цю справу вже створив :)