Phalcon & Volt: добавление условий hasMany()/belongsTo() и подсчет связанных строк

У меня есть две таблицы в моей базе данных, form_settings и webmaster, которые находятся в отношениях "один ко многим", и это было определено в их моделях.

FormSettings.php

class FormSettings extends \Phalcon\Mvc\Model
{    
    public function initialize()
    {
        $this->hasMany('db_table', 'webmaster', 'db_table');
    }
}

Webmaster.php

class FormSettings extends \Phalcon\Mvc\Model
{    
    public function initialize()
    {
        $this->belongsTo('db_table', 'form_settings', 'db_table');
    }
}

В моем контроллере я выполняю следующее find() и передаю его в представление:

ControllerBase.php

class ControllerBase extends Controller
{
    public function initialize()
    {
        $exhibitions = FormSettings::find(
            array(
                'form_type = "v" AND show_end_date > NOW() AND archived = "n"',
                'order' => 'db_table'
            )
        );

        $this->view->exhibitions = $exhibitions;
    }
}

И я знаю, что он правильно связывает строки из моей таблицы webmaster, так как у меня есть следующий код в моем представлении, и он отображает значения webmaster_id:

индекс.вольт

{% for exhibition in exhibitions %}
    <li>
        {{ link_to('index/browse/' ~ exhibition.db_table, exhibition.db_table) }}
        <!-- testing below -->
        {% for webm in exhibition.webmaster %}
            {{ webm.webmaster_id }}
        {% endfor %}
        <!-- end testing -->
    </li>
{% endfor %}

Мой вопрос состоит из трех частей:

  1. Как я могу только связать webmaster строк, в которых столбец extra_1 не является NULL?
  2. Как я могу count() связать webmaster строк для каждого db_table (уникального в form_settings)?
  3. Как я могу передать эту информацию в представление в моем объекте $exhibitions, чтобы я мог повторить синтаксис count() в вольтах?

person mpdc    schedule 23.08.2016    source источник


Ответы (1)


Привет, и прежде всего спасибо за хорошее форматирование вопроса.

Извините меня за использование примеров, которые используют мою текущую структуру базы данных. Но вы можете легко обновить свой код.

1) Вы можете задать дополнительные параметры для определения отношения.

$this->hasMany('id', 'Models\News', 'category_id', [
    'alias' => 'news',
    'reusable' => true, 
    'params' => [
        'order' => 'id DESC',
        'conditions' => 'extra_1 IS NOT NULL',
    ]
]);

Обратите внимание на reusable выше. При его использовании запрос выполняется только один раз для каждого запроса. Учитывая, что вы хотите подсчитывать записи и перебирать их, это хороший прирост производительности.

2 + 3) Перебор результатов в вольтах и ​​подсчетах:

Код контроллера:

$this->view->categories = \Models\NewsCategories::find();

Вольт:

{% for category in categories %}
    {% if category.news|length > 0 %} // Do not print categories without articles
    <h3>Category #{{ category.id }} with total of {{ category.news|length }} articles.</h3>
    <ul>
    {% for item in category.news %}
        <li>News #{{ item.id }}</li>
    {% endfor %}
    </ul>
    {% endif %}
{% endfor %}

Приведенный выше код в моем случае дает следующий результат:

Категория №4, всего 4 статьи.

  • Новость №3
  • Новость №4
  • Новость №5
  • Новость №7

Категория №5, всего 1 статья.

  • Новости №1

person Nikolay Mihaylov    schedule 23.08.2016
comment
for category in categories for item in category.news НЕТ ПРОСТО НЕТ, это создаст МНОГО запросов к базе данных. Если вам нужно выбрать только идентификаторы новостей, используйте group_concat, чтобы выбрать их с помощью построителя запросов в той же строке, что и категория, и правильно отобразить их в volt. - person Juri; 24.08.2016
comment
Это был просто пример, иллюстрирующий вопрос @mpdc. Он хотел знать, как передавать параметры отношениям модели и как считать элементы в вольтах. Никто не говорит, что это лучшая практика :) - person Nikolay Mihaylov; 24.08.2016