Минимизировать вызовы к контроллеру из шаблона SilverStripe

В приложении Silverstripe, которое я создаю, у меня есть NewsArticles, у которых есть NewsTags (создано с использованием silverstripe-tagfield). Я использую NewsTags для создания виджета «Связанные новости» на боковой панели каждого NewsArticle. Я создал действие RelatedArticles в контроллере NewsArticle, и все работает отлично.

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

Вот урезанная версия моего файла шаблона RelatedNewsModule.ss:

// First call to check if there are related articles
<% if $RelatedArticles %>

    // second call to get the array
    <% loop $RelatedArticles() %>
        ...
    <% end_loop %>

    // third call to check if there are more than one so we need navigation
    <% if $RelatedArticles.Count > 1 %>
            ... navigation markup
    <% end_if %>

<% end_if %>

Я хотел бы вызвать функцию один раз и, возможно, использовать свойства в шаблоне SilverStripe, которые будут ссылаться на две проверки и массив статей. Однако я не знаю, как это сделать.

Как лучше всего справиться с этой ситуацией?


person rath3r    schedule 04.02.2016    source источник
comment
Скобки в петле не нужны. И обычно он должен кэшировать запрос, поэтому if $RelatedArticles и loop $RelatedArticles, по крайней мере, для отношений $ has_many или $ many_many. В вашем случае вы будете кешировать его вручную в своем действии. См. Также docs.silverstripe.org/en/3.1/developer_guides/ производительность /   -  person wmk    schedule 05.02.2016
comment
Хорошо. Сниму скобки и посмотрю. Что касается кеша, причина, по которой я задал вопрос, заключалась в том, что я заметил, что во время его отладки var_dump вызывается 3 раза.   -  person rath3r    schedule 05.02.2016
comment
ну, вам нужно будет проверить, запрашивается ли БД три раза или она кэшируется. Просто введите? Showqueries = 1 в свой URL. См. docs.silverstripe.org/en/3.2/developer_guides/debugging/   -  person wmk    schedule 05.02.2016
comment
@ rath3r Самый простой способ постоянно предотвращать ненужные запросы - использовать частичное кэширование с агрегатом. docs.silverstripe.org/en/3.2/developer_guides/performance/ таким образом он будет делать их только тогда, когда требуется признание недействительности.   -  person Olli Tyynelä    schedule 05.02.2016
comment
Например, кешируйте дорогостоящий запрос в его собственный блок, проверьте счетчик или любое значение, по которому вы хотите его агрегировать. Я, конечно, не подключаюсь к базе данных для проверки значений, но они довольно быстро запускаются в sql. Получение полных данных и манипулирование дисплеем - это то, что обычно вызывает снижение производительности.   -  person Olli Tyynelä    schedule 05.02.2016


Ответы (1)


Как сказано в комментариях, SilverStripe должен вызывать базу данных только один раз и кэшировать RelatedArticles результаты для следующих 2 вызовов.

Для дальнейшего кэширования запросов мы можем использовать частичное кэширование для кэширования частей шаблон.

<% cached 'RelatedArticles', $ID, $List('RelatedArticles').max('LastEdited'), $List('RelatedArticles').count() %>
    <% if $RelatedArticles %>

        // second call to get the array
        <% loop $RelatedArticles %>
            ...
        <% end_loop %>

        // third call to check if there are more than one so we need navigation
        <% if $RelatedArticles.Count > 1 %>
            ... navigation markup
        <% end_if %>

    <% end_if %>
<% end_cached %>
person 3dgoo    schedule 08.02.2016