Создание блога

miketomlin

Новичок
Ну это как-то костыльно...
В чем костыльно?..

Независимо от того, какие идентификаторы нужны в адресах, имена обязательных полей всегда одинаковы. Если по минимуму, то id может быть единственным обязательным полем. Двоякость типа поля проще поддерживать, чем двоякость имени поля с идентификаторами для адресов. Если не дублировать числовые id в слагах, когда слагов по сути нет. Но а если дублировать, то «как-то костыльно» делать выборку по таким слагам вместо числовых id.
 
Последнее редактирование:

firep91613

Новичок
Смотрю сейчас схему комментариев у вордпресс. Там у таблицы comments есть внешний ключ post_id, ну это понятно. И есть parent, видимо для реплик. Правильно ли я понимаю, что эта колонка нужна чтобы хранить id коммента, к которому эта реплика относится?

Ну т.е. нажимая на кнопку "ответить", JS'ом вставляется форма и отправляется со всеми данными тоже аяксом, в том числе и id коммента, которому ответили. И этот id пишется в колонку parent. Сама колонка nullable по умолчанию. Так чтоли получается?
 

miketomlin

Новичок
Я думаю у каждой колонки должно быть свое предназначение. Можно и слаг и айди хранить. Тут, например и айди и слаг - Создание-блога.88142/page-14
Так упомянутый подход этому не мешает. Когда ты объединяешь в адресе слаг и числовой id, числовой практически всегда первичен, а слаг играет роль оформительского довеска. В этом случае будут поля id и, например, slug. Когда в адресе используется только слаг, он является полноценным идентификатором, но при этом числовой, естественно, никто не запрещает использовать. В этом случае слаг будет в поле id, а числовой идентификатор в поле с другим именем. Есть как мин. еще два формата имени помимо просто id. У нас такое поле обычно называют в соответствии с описываемой сущностью и именем таблицы, например user в таблице prefix_user. У фреймворков много заточенных под это дело методов и функций. Но в принципе и это не обязательное требование, например я часто называю таблицы сущностью во можественном числе, а поле с числовым id – в единственном или еще короче: post в таблице prefix_posts, art в таблице prefix_articles. Смысл в том, что во всей БД поля с одинаковыми идентификаторами могут называться одиково, ну и доп. бонус – USING(field).
 
Последнее редактирование:

firep91613

Новичок
Как по уму вставлять данные в аякс запрос? У меня пока есть черновой вариант, но судя по всему он никуда не годится.
JavaScript:
comments.addEventListener('submit', (e) => {
    if (!e.target.classList.contains('comment__form')) return;
    e.preventDefault();

    const parentElem = e.target.parentNode;
    const url = e.target.getAttribute('action');
    const token = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
    const data = {
        content: e.target.children[1].value,
        post_id: {{ $post->id }},
        user_id: @auth {{ Auth::user()->id }} @else 0 @endauth,
        parent_id: +e.target.dataset.id || null
    };

    fetch(url, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'X-CSRF-TOKEN': token
        },
        body: JSON.stringify(data)
    })
        .then(response => response.json())
        .then(data => {
            console.log(data);

            if (!data.comment.parent_id) {
                e.target.after(getCommentAfterPublishing(data));
                e.target.children[1].value = '';
            } else {
                if (!parentElem.parentNode.querySelector('.comment__replies')) {
                    const wrap = document.createElement('div');
                    wrap.classList.add('comment__replies');
                    parentElem.parentNode.append(wrap);
                    wrap.append(getCommentAfterPublishing(data));

                } else {
                    parentElem.parentNode.querySelector('.comment__replies').prepend(getCommentAfterPublishing(data));
                }

                document.querySelector('.comment__action-reply').click();
            }
        })
        .catch(error => {
            console.log(JSON.parse(error));
        });
});
Тут можно открыть консоль и поменять на что угодно:
PHP:
post_id: {{ $post->id }},
user_id: @auth {{ Auth::user()->id }} @else 0 @endauth,
В контроллере сверять текущего пользователя и то что пришло?
 

firep91613

Новичок
А как в реальных приложениях поступают с этим? Следует ли ловить этот эксепшен? Ну подумаешь, видно что Laravel и PHP. Laravel ведь не испугать SQL-инъекциями?
1651
 

AmdY

Пью пиво
Команда форума
Это дев мод, в продакшен проект выкатывается с другими настройками, там не будут светиться трейсы. Пусть валятся экспешины, по мере надобности настроишь их логирование.
Обязательно перечитай всю доку от начала до конца, а не только по мере необходимости.
 

firep91613

Новичок
Появилась идея отображать даты публикации комментариев к постам как тут на форуме и с учетом часовой зоны пользователя. Ну типо "Сегодня", "Вчера", в такой-то день и т.д. Этой задачей должен заниматься PHP или JS? Просто если PHP, то не понятно, как ему можно передать часовую зону пользователя. И сама дата в базе хранится по часовому поясу Гринвича. Я сделал так:
PHP:
<p class="comment__date">{{ $comment->created_at->format('Y-m-d H:i:s') }}</p>
JavaScript:
function getFormatDate(date) {
    const daysOfWeek = ['Воскресенье', 'Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота'];
    const monthsOfYear = ['Янв', 'Фев', 'Мар', 'Апр', 'Май', 'Июн', 'Июл', 'Авг', 'Сен', 'Окт', 'Ноя', 'Дек'];
    const currentDate = new Date();
    const currentDateMs = currentDate.getTime();
    const offset = currentDate.getTimezoneOffset() * 60 * 1000;
    const receivedDateMs = new Date(date).getTime() - offset;
    const receivedDate = new Date(receivedDateMs);
    const receivedDateDay = receivedDate.getDate();
    const currentDay = currentDate.getDate();
    const dayDiff = currentDay - receivedDateDay;
    const hours = (receivedDate.getHours() < 10) ? '0' + receivedDate.getHours() : receivedDate.getHours();
    const minutes = (receivedDate.getMinutes() < 10) ? '0' + receivedDate.getMinutes() : receivedDate.getMinutes();
    const pattern = `${hours}:${minutes}`;

    if (dayDiff === 0) {
        const diff = (currentDateMs - receivedDateMs);

        if (diff < 3600000) {
            if (diff < 60) {
                return 'Только что';
            }

            return `${Math.round(diff / 1000 / 60)} мин. назад`;
        }

        return 'Сегодня в ' + pattern;
    } else if (dayDiff === 1) {
        return 'Вчера в ' + pattern;
    } else if (dayDiff < 7) {
        return `${daysOfWeek[new Date(date).getDay()]} в ` + pattern;
    } else {
        return `${receivedDate.getDate()} ${monthsOfYear[receivedDate.getDay()]} ${receivedDate.getFullYear()}`;
    }
}

const allComments = [...document.querySelectorAll('.comment__date'), ...document.querySelectorAll('.comment__reply-date')];

for (let i = 0; i < allComments.length; i++) {
    allComments[i].innerText = getFormatDate(allComments[i].innerText);
}
Получается какая-то двойная работа... Сначала PHP пишет, потом JS за ним исправляет. Можно ли как-нибудь по грамотнее это реализовать?
 
Сверху