Crud: Search for custom accessor for select and select_multiple column

Created on 13 Nov 2017  路  8Comments  路  Source: Laravel-Backpack/CRUD

The brand new Ajax Table is nice...
There is a handy searchLogic for custom accessor too

However, I am using connected model with custom accessor, the $query string only stick with the current model but not the connected entity

is it really impossible to search for custom accessor for select and select_multiple column ??

Ask-It-On-Stack-Overflow

Most helpful comment

@lloy0076 you are right! whereHas is the answer!

'searchLogic' => function ($query, $column, $searchTerm) {
    $query->orWhereHas('cruise_ship', function ($q) use ($column, $searchTerm) {
        $q->where('name', 'like', '%'.$searchTerm.'%')
          ->orWhereDate('depart_at', '=', date($searchTerm));
    });
}

I hope you could include this in the readme. Thanks a lot !

All 8 comments

When you say "[you are] using connected model with custom accessor" what do you mean exactly?

Let me elaborate more on my scenario...

I am searching on "Price" eloquent model, which has relationship with "CruiseShip" & "Fee" model.
It is fine that if the "Fee" model using the attribute appear on the actual MySQL Table's column...

$this->crud->addColumn([
    'label' => "Fee Name",
    'type' => "select",
    'name' => 'fee_name_id',
    'entity' => 'fee_name',
    'attribute' => "name", // This is on the actual MySQL Table
    'model' => "App\Models\Fee",
]);  // This is perfectly fine

However, the column "CruiseShip"(the connected model) using the custom attribute (the customized Accessor which combined two columns) which is not the actual table's column...

$this->crud->addColumn([
    'label' => "Cruise Ship",
    'type' => "select",
    'name' => 'cruise_ship_id',
    'entity' => 'cruise_ship',
    'attribute' => "cruise_ship_name_date", // combined name & date column
    'model' => "App\Models\CruiseShip",
    'searchLogic' => function ($query, $column, $searchTerm) {
        $query->orWhere('name', 'like', '%'.$searchTerm.'%');  // Trying to query on actual "name" column 
    }
]);

This will get the SQL query error

"SQLSTATE[42S22]: Column not found: 1054 Unknown column 'name' in 'where clause' (SQL: select count(*) as aggregate from `prices` where (`name` like %m%))"

I understand that the $query is executing the SQL query for 'prices' table, I am wondering how can I query other connected table...

You sound like you want a whereHas or an orWhereHas (if such a thing exists); I think. Whether that $query will allow that or not is a different question.

I think what your saying is that you want to limit the thing in "cruise ships" where the name on the WHAT MODEL (crusise ship model?) is like 'some search term'.

It is because I am searching on "Price" not "CruiseShip" model.

"Price" is belongsTo "CruiseShip" model

the $query is looking to "prices" table only but not other table if i am using searchLogic feature

I hope the searchLogic feature can accept 'table' as an argument for better flexibility
or extend the searchLogic feature for related model with custom attribute.

Is $query a query builder?

I am not very sure on that. from the syntax i believe it is a query builder.
This is what i found from the source code.

https://github.com/Laravel-Backpack/CRUD/blob/0be2bae4a58ce417ddd5f8865b1b6e38ee87879d/src/CrudPanel.php

    // ------------------------------------------------------
    // BASICS - model, route, entity_name, entity_name_plural
    // ------------------------------------------------------

    /**
     * This function binds the CRUD to its corresponding Model (which extends Eloquent).
     * All Create-Read-Update-Delete operations are done using that Eloquent Collection.
     *
     * @param string $model_namespace Full model namespace. Ex: App\Models\Article]
     *
     * @throws \Exception in case the model does not exist
     */
    public function setModel($model_namespace)
    {
        if (! class_exists($model_namespace)) {
            throw new \Exception('This model does not exist.', 404);
        }

        $this->model = new $model_namespace();
        $this->query = $this->model->select('*');
        $this->entry = null;
    }

The searchLogic is defined and called in the Backpack\CRUD\PanelTraits\Search
CrudPanel.php uses this Traits and public $query is defined in CrudPanel.php ...
So, basically the $query tight with $this->model

@lloy0076 you are right! whereHas is the answer!

'searchLogic' => function ($query, $column, $searchTerm) {
    $query->orWhereHas('cruise_ship', function ($q) use ($column, $searchTerm) {
        $q->where('name', 'like', '%'.$searchTerm.'%')
          ->orWhereDate('depart_at', '=', date($searchTerm));
    });
}

I hope you could include this in the readme. Thanks a lot !

@kiddtang - thanks for the confirmation. Just updated the docs with your example. Cheers!

Was this page helpful?
0 / 5 - 0 ratings