└── README.md /README.md: -------------------------------------------------------------------------------- 1 | # Конвенция наименований в Laravel 2 | 3 | Для упрощения взаимодействия в Laravel придуманы правила наименований. Правила нужны везде, а если правила не только знать но и соблюдать, то это даёт значительный прирост в скорости разработки. 4 | 5 | Laravel наш помощник, но он будет помогать лишь в том случае, если вы работаете по его правилам! Применяя конвенцию наименований Laravel поможет автоматически находить нужные зависимые сущности! 6 | 7 | По большей части конвенция наименований охватывает слой взаимодействия с базой данных. 8 | 9 | Применение конвенции наименований в Laravel = простой, чистый и лаконичный код. 10 | 11 | Погнали! 12 | ---- 13 | 14 | # Оглавление 15 | - [Общие правила](#terms) 16 | - [Таблицы базы данных](#tables) 17 | - [Связующие таблицы BelongsToMany](#tables-pivot) 18 | - [Поля](#tables-columns) 19 | - [Primary key](#tables-pk) 20 | - [Foreign keys](#tables-fk) 21 | - [Models](#models) 22 | - [Константы](#models-constants) 23 | - [Свойства(Поля таблицы)](#models-attributes) 24 | - [Методы](#models-methods) 25 | - [Acccessors/Mutators](#models-am) 26 | - [Local scopes](#models-scopes) 27 | - [Отношения](#models-relations) 28 | - [Миграции](#migrations) 29 | - [Фабрики](#factories) 30 | - [Политики/Policy](#policies) 31 | - [Директории](#directories) 32 | - [Controllers](#controllers) 33 | - [Routes](#routes) 34 | - [Blade](#blade) 35 | - [Json response](#json) 36 | 37 | 38 | 39 | ### Общие правила 40 | 1. Всегда в названиях используйте точное значение слова на английском. Не надо использовать транслит.
41 | *Если не знаете перевод слова или как оно правильно пишется - просто найдите его перевод. Заодно и словарный запас расширите)* 42 | 2. Избегайте ошибок в написании. 43 | 3. Старайтесь подбирать название так, чтобы сразу было понятно, что именно содержится в именовании. 44 | 4. Не сокращайте названия без острой необходимости. 45 | ```php 46 | // плохо 47 | $acc 48 | $conn 49 | $descr 50 | prepResp() 51 | regEvtHandler() 52 | updCom() 53 | 54 | // хорошо 55 | $account 56 | $connection 57 | $description 58 | prepareResponse() 59 | registerEventHandler() 60 | updateComment() 61 | ``` 62 | 63 | 64 | 65 |
66 | 67 | ### Таблицы базы данных 68 | 69 | 70 | Для оформлении названий таблиц принято использовать имена во множественном числе с нотацией snake_case: 71 | 72 | > snake_case — стиль написания составных слов, при котором несколько слов разделяются символом подчеркивания. Слова как бы ползут по строке, в результате получается дли_и_инное, как змея, название. В данном гайде snake_case всегда в нижнем регистре 73 | 74 | 75 | **Примеры**: 76 | - `users` 77 | - `products` 78 | - `order_products` 79 | 80 | **Исключение** 81 | 82 | Связующие таблицы для отношений `BelongsToMany`. 83 | 84 | 85 | 86 | #### Связующие таблицы BelongsToMany 87 | 88 | Применяем snake_case + имена двух таблиц, которые будем связывать, в единственном числе. В качестве разделителя между именами таблиц используем символ нижнего подчёркивания `_`. 89 | 90 | Сортируются сущности между разделителем в алфавитном порядке. 91 | 92 | Разберём на примере: есть таблицы `users` и `tasks`, приводим обе таблицы в единственное число и разделяем через подчеркивание. Буква `t` в алфавите следует раньше `u`, поэтому результат связи двух таблиц будет - `task_user`. 93 | 94 | Ну или пример посложнее: `order_products` и `properties`! Результат - `order_product_property`. 95 | 96 | **Примеры**: 97 | - `task_user` 98 | - `event_place` 99 | - `order_product_property` 100 | 101 | 102 | 103 | #### Поля таблицы 104 | Все просто - snake_case. И не забывайте общие правила о которых мы писали в одноименном разделе 105 | 106 | **Примеры**: 107 | - `created_at` 108 | - `seo_title` 109 | 110 | 111 | 112 | #### Primary Key 113 | По умолчанию Laravel ожидает `id`. 114 | 115 | 116 | 117 | #### Foreign Keys 118 | 119 | snake_case в формате - имя таблица в единственном числе, далее подчеркивание `_` и далее Primary key ('id'). 120 | Пример - страна пользователя, где все страны в таблице `countries`, пользователь в таблице `users` 121 | имеет foreign key для связи со страной - `country_id`, формат `{связанная_таблица_в_единственном_числе}_{primary_key_связанной_таблицы}` 122 | 123 | **Примеры**: 124 | - `country_id` 125 | - `order_product_id` 126 | 127 | 128 | 129 | ### Models 130 | PascalCase в единственном числе 131 | 132 | > PascalCase — это стиль написания имен, при котором составные слова названия идентификатора (в том числе и первое слово) пишутся слитно, и каждое новое слово начинается с большой буквы. Пример: MyVar, MyBestProgramm, WorkArray. 133 | > Паскаль нотация используется для названий классов и публичных полей данных, а также именования процедур и функций. 134 | 135 | Если мы соблюдали конвенцию наименований для таблиц, то Laravel автоматически определит таблицу для модели. Как? Приведет вашу модель в snake_case в нижнем регистре добавит подчеркивания '_' и переведёт в множественное число. Получится имя таблицы. 136 | 137 | В итоге `User` будет ссылаться к таблице `users`, `OrderProduct` к `order_products` 138 | 139 | **Проблемы нарушения конвенции наименований**: 140 | - Если название таблицы указано не в snake_case (или название таблицы отличается от названия модели) потребуется указать в модели свойство, помогающее определить таблицу: `protected $table = 'tableName';` 141 | - тоже самое в случае с primary key - `protected $primaryKey = 'primaryKey';` 142 | - и еще масса побочных указаний для отношений) 143 | 144 | **Директория по умолчанию** 145 | 146 | `app/Models` 147 | 148 | **Примеры**: 149 | - `User` 150 | - `Product` 151 | - `OrderProduct` 152 | 153 | 154 | 155 | #### Константы 156 | 157 | При оформлении названия используем UPPER_CASE с разделителем подчеркивания. 158 | 159 | **Примеры**: 160 | ```php 161 | class Document 162 | { 163 | const STATUS_ACTIVE = 1; 164 | const STATUS_DELETE = 2; 165 | const STATUS_ARCHIVE = 9; 166 | } 167 | ``` 168 | 169 | 170 | 171 | #### Свойства (Поля таблицы) 172 | Свойства модели ссылаются на поля таблицы и имеют точно такие же наименования в snake_case. 173 | 174 | Становятся доступными за счет магических php методов. Обращаясь к свойствам модели, Laravel автоматически 175 | соотнесет их с полями в таблице (если такие существуют). 176 | 177 | **Примеры**: 178 | - `$model->created_at` 179 | - `$model->seo_title` 180 | 181 | 182 | 183 | #### Методы (не только в моделях, везде :)) 184 | 185 | При оформлении названия используем camelCase: 186 | 187 | > camelCase - стиль написания составных слов, при котором несколько слов пишутся слитно без пробелов, при этом каждое слово внутри фразы пишется с прописной буквы. Начинается с маленькой буквы. И получается верблюд (camel) с его горбами. 188 | 189 | **Примеры**: 190 | - `getSomething()` 191 | 192 | 193 | 194 | #### Accessors/Mutators 195 | Наименования поля в таблице приводится к camelCase и изменяется в методе 196 | [Отлично расписано в официальной документации](https://laravel.com/docs/eloquent-mutators#accessors-and-mutators) 197 | 198 | 199 | 200 | #### Local Scopes 201 | camelCase с префиксом scope 202 | [Отлично расписано в официальной документации](https://laravel.com/docs/eloquent#local-scopes) 203 | 204 | 205 | 206 | #### Отношения 207 | Все просто - camelCase для модели с которой мы формируем отношение. Если отношение к одной записи, тогда именование оформляем в единственном числе, а если несколько - то во множественном числе! 208 | 209 | Рассмотрим примеры для модели `User` c разным типом отношений к модели `Country`. 210 | 211 | **Примеры**: 212 | - `belongsTo, hasOne, hasOneThrough, morphOne` = `country()` 213 | - `belongsToMany, hasMany, hasManyThrough, morphMany, morphToMany` = `countries()` 214 | 215 | **Проблемы нарушения конвенции наименований**: 216 | - Может потребоваться указать `foreign_key` `return $this->hasOne(Phone::class, 'foreign_key');` 217 | - Может потребоваться указать `foreign_key` и `local_key` `return $this->hasOne(Phone::class, 'foreign_key', 'local_key');` 218 | - Может потребоваться указать и связующую таблицу и ключи `return $this->belongsToMany(Role::class, 'role_user', 'user_id', 'role_id');` 219 | 220 | 221 | 222 | ### Миграции 223 | `php artisan make:migration migration_name` 224 | 225 | Команда выше просто создаст пустой файл миграции, где методы up и down будут пустыми. 226 | 227 | ```php 228 | public function up() 229 | { 230 | // 231 | } 232 | 233 | public function down() 234 | { 235 | // 236 | } 237 | ``` 238 | 239 | Но мы также можем влиять на содержимое миграций, если будем придерживаться правил наименования, тем самым упрощая нам жизнь. 240 | 241 | `php artisan make:migration create_users_table` 242 | 243 | Мы дали понять, что хотим создать таблицу users - `create_{Имя_таблицы}_table` 244 | 245 | Ключевое здесь `create_{Имя_таблицы}`, а вот table в конце можно пропустить 246 | 247 | В итоге получили: 248 | 249 | ```php 250 | public function up() 251 | { 252 | Schema::create('users', function (Blueprint $table) { 253 | $table->id(); 254 | $table->timestamps(); 255 | }); 256 | } 257 | 258 | public function down() 259 | { 260 | Schema::dropIfExists('users'); 261 | } 262 | ``` 263 | 264 | 265 | `php artisan make:migration add_column_to_users_table` 266 | 267 | В данном примере мы сообщаем Laravel о нашем желании модифицировать таблицу и ключевое здесь `to_{Имя_таблицы}`, а вот table в конце можно пропустить 268 | 269 | ```php 270 | public function up() 271 | { 272 | Schema::table('users', function (Blueprint $table) { 273 | // 274 | }); 275 | } 276 | 277 | public function down() 278 | { 279 | Schema::table('users', function (Blueprint $table) { 280 | // 281 | }); 282 | } 283 | ``` 284 | 285 | 286 | 287 | ### Фабрики 288 | **Директория по умолчанию** 289 | 290 | `database/factories` 291 | Взаимодействовать с фабриками мы можем посредством метода `factory()` в моделях. Модель автоматически определит к какому классу фабрики ей ссылаться если соблюдать конвенцию наименований. 292 | 293 | Те же правила что и для модели, только добавляем суффикс `Factory`! 294 | Формат - `{ИмяМодели}Factory` 295 | 296 | **Примеры**: 297 | - Модель `User`, а фабрика `UserFactory` 298 | - Модель `OrderProduct`, фабрика `OrderProductFactory` 299 | 300 | 301 | 302 | ### Политики (Policy) 303 | **Директория по умолчанию** 304 | 305 | `app/Policies` 306 | 307 | Laravel может автоматически определить политику для модели при соблюдении конвенции наименований. 308 | В таком случае политику не требуется регистрировать "вручную". 309 | 310 | Используем те же правила, что и для модели, только добавляем суффикс `Policy`! 311 | Формат - `{ИмяМодели}Policy` 312 | 313 | **Примеры**: 314 | - Модель `User`, а политика `UserPolicy` 315 | - Модель `OrderProduct`, политика `OrderProductPolicy` 316 | 317 | # Практика наименований остальных сущностей 318 | 319 | Никак не влияют на взаимодействие с Laravel, но делают код понятнее для всех кто будет с ним взаимодействовать. 320 | 321 | 322 | 323 | ### Директории 324 | PascalCase во множественном числе. 325 | 326 | **Примеры**: 327 | - `Models` 328 | - `QueryBuilders` 329 | - `Filters` 330 | 331 | Laravel дает свободу в расположении сущностей и наименовании директорий. 332 | 333 | Как пример, если мы используем `DDD подход`, то нас никто не ограничивает перенести всю бизнес логику в директорию `src`. Также перенести в `src` `/app` и назвать скажем `App` 334 | 335 | Но сами группы абстракций в хороших практиках именуются как в примере выше. 336 | 337 | 338 | 339 | ### Controllers 340 | **Директория по умолчанию** 341 | 342 | `app/Http/Controllers` 343 | 344 | PascalCase в единственном числе c суффиксом Controller. 345 | 346 | **Примеры** 347 | - `CatalogController` 348 | - `ProductController` 349 | - `OrderController` 350 | - `BlogController` 351 | 352 | 353 | 354 | ### Routes 355 | snake_case либо kebab-case, пользуйтесь здравым смыслом выбирая между единственным либо множественным числом. 356 | `apiResource` и `resource` указываются во множественном числе, несмотря на то, что контроллер остается в единственном числе. 357 | 358 | 359 | > kebab-case стиль написания в котором слова в нижнем регистре разделяют символом дефиса. Можно представить, что слова при этом как бы насаживают на шампур — вот и получается шашлык (kebab). 360 | 361 | **Примеры** 362 | - `Route::get('catalog', CatalogController::class)` 363 | - `Route::get('categories', CategoryController::class)` 364 | - `Route::resource('users', UserController::class)` 365 | - `Route::apiResource('users', UserController::class)` 366 | 367 | 368 | 369 | ### Blade 370 | #### views директории 371 | snake_case во множественном числе, несмотря на то, что контроллер остается в единственном числе. 372 | 373 | #### blade шаблоны 374 | snake_case 375 | 376 | 377 | 378 | ### Json response 379 | Ключи в snake_case 380 | --------------------------------------------------------------------------------