We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Criteria with 2 models and same named fields

Hello

I use Phalconphp 3.4

I have two models with same named fields, model products with active field an categories with active field (We can think about created, modified, name field...). The problem, when I make a search and I want to filter products and categories I can't do that because the same named fields (aplicattion crash) and put model name, Products.active and Categories.active in input does not work. Is there a way to do that or is a bug?

Regards.

Paste Your code



3.1k
edited Oct '19

My real code. My view: And I remember inputs with models does not work too, I mean Espacios.name and Usuarios.name

<div class="box">
<?php
    echo $this->tag->form(
        [
            "admin/espacios/index",
            "autocomplete" => "off",
            "class" => "form-row"
        ]
    );
?>
<div class="form-group col-md-4 col-sm-4 col-xs-12">
    <label for="fieldEspacioName">Nombre espacio</label>
    <?php echo $this->tag->textField(["name", "size" => 30, "class" => "form-control", "id" => "fieldEspacioName"]); ?>
</div>
<div class="form-group col-md-4 col-sm-4 col-xs-12">
    <label for="fieldNombreUser">Nombre usuario</label>
    <?php echo $this->tag->textField(["name", "size" => 30, "class" => "form-control", "id" => "fieldNombreUser"]); ?>
</div>

<div class=" col-md-12 col-sm-12 col-xs-12 textcenter">
    <?php echo $this->tag->submitButton(["Buscar", "class" => "btn btn-default"]); ?>
</div>
<?php echo $this->tag->endForm(); ?>
</div>

Model Espacios and Usuarios have the same field:

/**
 *
 * @var string
 */
public $name

Controller (Criteria + Paginator + Query with Joins), all is ok within same field.

$numberPage = 1;
if ($this->request->isPost()) {
    $query = Criteria::fromInput($this->di, 'Salamandra\Models\Admin\Espacios', $_POST);
    $params = $query->getParams();
    $queryPart = Criteria::fromInput($this->di, 'Salamandra\Models\Admin\Usuarios', $_POST);
    $paramsPart = is_null($queryPart->getParams()) ? null : $queryPart->getParams();
    if(isset($paramsPart) && !empty($paramsPart)){
        if (isset($params['conditions']) && !empty($params['conditions']) && (isset($paramsPart['conditions']) && !empty($paramsPart['conditions']))) {
            $params['conditions'] .= ' and ' . $paramsPart['conditions'];
            $params['bind'] = array_merge($paramsPart['bind'], $params['bind']);
        } elseif (isset($paramsPart['conditions']) && !empty($paramsPart['conditions'])) {
            $params = $paramsPart;
        }
    }
    $this->session->set('condiciones-espacios-buscar', $_POST);
    $this->persistent->parameters = $params;
    if (!empty($_POST['ordenar_por'])) {
        $ordenarPor = 'Espacios.' . $_POST['ordenar_por'] . ' DESC';
        $this->session->set('condiciones-ordenar-espacios-buscar', $ordenarPor);
    } else {
        $this->session->remove('condiciones-ordenar-espacios-buscar');
    }
} else {
    if ($this->session->has('condiciones-ordenar-espacios-buscar')) $ordenarPor = $this->session->get('condiciones-ordenar-espacios-buscar');
    $numberPage = $this->request->getQuery("page", "int");
}
$parameters = $this->persistent->parameters;
if (!is_array($parameters)) {
    $parameters = [];
} else {
    // si pagina mantenemos los valores de los input en la vista
    $_POST = $this->session->get('condiciones-espacios-buscar');
}
// con el builder cogemos solo el data necesario para el paginador y en el createBuilder podemos insertar
// los parĂ¡metros del componente Criteria
$builder = $this->modelsManager->createBuilder($parameters)
    ->columns(['Espacios.nombre_espacio AS nombre_espacio', 'Espacios.created AS created', 'Usuarios.nickname AS nickname', 
                'Espacios.id AS id', 'Usuarios.nickname AS apellidos', 'MensajesTiemposRespuesta.tiempo_respuesta AS tiempo_respuesta',
                'MensajesTiemposRespuesta.total_mensajes as total_mensajes', 'Espacios.activo_espacio as activo', 'Espacios.slug as slug',
                'Espacios.modified AS modified'])
    ->from(['Espacios' => 'Salamandra\Models\Admin\Espacios'])
    ->leftJoin('Salamandra\Models\Admin\Usuarios', 'Usuarios.id = Espacios.usuario_id', 'Usuarios')
    ->leftJoin('Salamandra\Models\MensajesTiemposRespuesta', 'Espacios.id = MensajesTiemposRespuesta.espacio_id', 'MensajesTiemposRespuesta')
    ->orderBy($ordenarPor);
$paginator = new PaginatorQueryBuilder(
    [
        'builder' => $builder,
        'limit'   => 15,
        'page'    => $numberPage,
    ]
);
$this->view->page = $paginator->getPaginate();

In my humble opinion, Your code is way overcomplicated, but, what You can do, is to try distinguish those two fields by using "table.fieldName" syntax in Your DB query, instead of just "fieldName", because that probably is causing the problem.

So, use Espacios.name = POST VALUE and Usuarios.name = POST VALUE

instead of just name which is ambioguous, that is probably the problem.



3.1k

That I told, this: Espacios.name and Usuarios.name, does not work

In my humble opinion, Your code is way overcomplicated, but, what You can do, is to try distinguish those two fields by using "table.fieldName" syntax in Your DB query, instead of just "fieldName", because that probably is causing the problem.

So, use Espacios.name = POST VALUE and Usuarios.name = POST VALUE

instead of just name which is ambioguous, that is probably the problem.

Does application produce any error before it crashes, like in error log or onto the screen?

Also try this:

try {
    $this->view->page = $paginator->getPaginate();
}
catch (\Exception $e) {
    echo 'Error message: '.$e->getMessage();
}

and see if it produce any error on screen.



3.1k
edited Oct '19

Ok, this told me something normal: is ambiguous.

But i see something wrong, If i put Espacios.name into the input then in my controller the $_POST variable is like that: Espacios_name, so I don't know why and classic input html5 the same.

Of course I can format this input in my controller Espacios_name = Espacios.name and it is works but this format Espacios_name....Something that i don't know.

Does application produce any error before it crashes, like in error log or onto the screen?

Also try this:

try {
  $this->view->page = $paginator->getPaginate();
}
catch (\Exception $e) {
  echo 'Error message: '.$e->getMessage();
}

and see if it produce any error on screen.

Well to be honest, I don't use Phalcon forms, so maybe someone who does will help You.

Anyway, maybe converting "Espacios_name" to "Espacios.name" will do the trick, and fix Your problem?



3.1k

Yes, I did it but isn't elegant, but at last is better than nothing.

Well to be honest, I don't use Phalcon forms, so maybe someone who does will help You.

Anyway, maybe converting "Espacios_name" to "Espacios.name" will do the trick, and fix Your problem?

Thanks for sharing. I found a lot of interesting information here. A really good post, very thankful and hopeful that you will write many more posts like this one. fireboy and watergirl