Поиск Symfony, параметр не отправляется

мои объекты: реклама - это отношение OneToMany к адресу, а адрес - это отношение OneToMany с городом. В City у меня есть около 200 городов, которые пользователь может выбрать 1 из EntityType. Я пытаюсь создать поисковую систему (?), В которой пользователь может фильтровать рекламу по городу. Я не уверен, что знаю, как это сделать, мой searchController имеет 1 действие:

/**
 * @Route("/search/city", name = "search_city")
 *
 * @param Request $request
 * @return \Symfony\Component\HttpFoundation\Response
 */
public function searchCityAction(Request $request)
{
    $search = new City();

    $form = $this->createForm(CityType::class, $search)
        ->add('submit', SubmitType::class, ["label" => "Szukaj"]);


    $entityManager = $this->getDoctrine()->getManager();


    if ($request->isMethod(Request::METHOD_POST))
    {
        $form->handleRequest($request);

        $selectedCity = ($_REQUEST['city']['city']);

        $address = $entityManager->getRepository(Address::class)->findBy(["city" => $selectedCity]);
        $searched = $entityManager->getRepository(Advert::class)->findBy(["address" => $address]);

        return $this->render("Search/searched.html.twig", ["searched" => $searched]);
    }


    return $this->render("Search/index.html.twig", ["form" => $form->createView()]);
}

index.html.twig:

{% extends 'base.html.twig' %}

{% block body %}
    {{ form(form) }}
{% endblock %}

search.html.twig:

{% extends 'base.html.twig' %}

{% block body %}
    {% for search in searched %}
        {{ search.title }}
    {% endfor %}
{% endblock %}

В контроллере в $ selectedCity я получил хороший идентификатор города. Но позже почему-то параметр отсутствует. В объекте Advert я получил переменную $ address, в адресе я получил переменную $ city, и я попытался взять ее из БД в этих двух строках:

$address = $entityManager->getRepository(Address::class)->findBy(["city" => $selectedCity]);
$searched = $entityManager->getRepository(Advert::class)->findBy(["address" => $address]);

но в любом случае это не работает, и я думаю, что я много совмещал и заблудился здесь

Редактировать

Я попытался сделать это первое решение, но оно не работает. Я изменил свой код примерно так:

if ($request->isMethod(Request::METHOD_POST))
    {
        $form->handleRequest($request);

        $selectedCity = ($_REQUEST['city']['city']);

        $address = $entityManager->getRepository(Address::class)->findBy(["city" => $selectedCity]);
        $addressIds = $address->map(function($single_address) {
            return $single_address->id;
        });
        $searched = $entityManager->getRepository(Advert::class)->findBy(["address" => $addressIds]);

        return $this->render("Search/searched.html.twig", ["searched" => $searched]);
    }

method "map" not found in array...

Ошибка на сайте:

Call to a member function map() on array

Вот код переменных определения из моих сущностей:

Класс рекламы:

/**
 * @var Address
 *
 * @ORM\ManyToOne(targetEntity = "Address", inversedBy = "adverts", cascade = {"persist"})
 */
private $address;

Класс адреса:

/**
 * @var Advert[]|ArrayCollection
 *
 * @ORM\OneToMany(targetEntity = "Advert", mappedBy = "address")
 * @ORM\JoinColumn(name = "address_id", referencedColumnName = "id")
 */
private $adverts;

/**
 * @var City
 *
 * @ORM\ManyToOne(targetEntity = "City", inversedBy = "addresses")
 */
private $city;

Класс города:

/**
 * @var Address[]|ArrayCollection
 *
 * @ORM\OneToMany(targetEntity = "Address", mappedBy = "city")
 * @ORM\JoinColumn(name = "city_id", referencedColumnName = "id")
 */
private $addresses;

Я думаю, вам лучше создать репозиторий, чтобы у вас был метод поиска по каждому из них. Затем используйте Criteria шаблон (это показывает еще один интересный вариант использования) с параметрами для частей поиска и вызовите его из метода вашего контроллера: $results = $this->addrRepo->searchByCity($cityName);

Jared Farrish 05.05.2018 18:11

Или (например) вы можете объединить критерии (как в примере Knp), чтобы расширить параметры поиска: $this->addrRepo->searchByCriteria($criteria), где $criteria представляет собой массив объектов Criteria для применения.

Jared Farrish 05.05.2018 18:16

можешь пошагово объяснить, как это сделать на моем примере? Я действительно потерялся здесь

paprykarz 06.05.2018 12:09
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
3
60
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Когда вы запрашиваете сущности из базы данных с помощью метода Doctrine Entity Manager findBy, данные будут возвращены как ArrayCollection объектов Entity. Следовательно, вы не можете передавать их напрямую как параметр другой функции findBy.

В примере, который вы публикуете, $address представляет собой коллекцию экземпляров Address. Вы можете извлечь массив идентификаторов из коллекции и запросить их у Advert. Например:

$searched = $entityManager->getRepository(Advert::class)->findBy(["address" => $addressIds]);

Предположим, что класс Address имеет свойство ключа по умолчанию, называемое id, вы можете извлечь список идентификаторов адресов с помощью функции ArrayCollection.map:

$addressIds = $addresses->map(function($single_address) {
   return $single_address->id;
})

Это единственный способ добиться того, что вы пытаетесь сделать. Но не единственный и лучший способ.

В основном, если вы устанавливаете связь bi-directional (2 способа) между Address и сущностью Advert. Вы можете просто получить доступ к списку сущностей Advert, связанных с сущностью Address, используя:

$address->adverts

Я предполагаю, что ваш adverts является свойством класса Address, сопоставленного с классом Advert.

Еще один запрос и установление отношений с Doctrine и Symfony можно найти здесь: https://symfony.com/doc/current/doctrine.html

Да, наконец, это работает. Мне пришлось немного изменить ваш код, например: $ addressIds = array_map (function ($ single_address) {return $ single_address-> id;}, $ address);

paprykarz 06.05.2018 15:09

Рад слышать, что это помогает, код, который я опубликовал, является просто примером, основанным на предположении, что ваша версия Symfony ArrayCollection поддерживает вспомогательную функцию, такую ​​как map. Если вы сочтете это полезным, не могли бы вы проголосовать за него или отметить ответ как принятый.

Thai Duong Tran 06.05.2018 16:08

Другие вопросы по теме