└── 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 |
--------------------------------------------------------------------------------