No searching on primary key with Laravel Scout? - php

I'm using Laravel Scout with TNTSearch Engine at it's working fine but with one little problem. I have the following records.
| ID | Name |
+---------+----------+
| 9030100 | Car |
| 9030150 | Car2 |
| 9030200 | Radio |
Here is my query:
CatalogProducts::search( $query )->paginate( 15 );
When I'm looking for 'car,' it's returning all records with 'car' in the name.
When I'm looking for '9030100', it's returning the product 'Car.'
But when I'm looking for '9030', I don't have any results. Why? How do I fix it?

try changing the fuzziness.
set fuzziness to true.
'tntsearch' => [
'storage' => storage_path(), //place where the index files will be stored
'fuzziness' => true,
'fuzzy' => [
'prefix_length' => 2,
'max_expansions' => 50,
'distance' => 2
],
'asYouType' => false,

Related

Using select2_from_ajax with a JSON datasource

I am new to Laravel and to Backpack for Laravel so please bear with me. I am trying to create a client registration form that features a "State" field which is populated dynamically depending on the value selected for the "Country" field.
I am following the instructions provided by Backpack's author here: https://backpackforlaravel.com/docs/3.5/crud-fields#select2_from_ajax
Both states and countries come from this dataset: https://github.com/antonioribeiro/countries. They are returned as collections but they are not read from the DB.
Table schema for Clients (simplified)
+-------------------+---------+--------+
| Field | Type | Length |
+-------------------+---------+--------+
| uuid | CHAR | 36 |
| name | VARCHAR | 128 |
| city | VARCHAR | 128 |
| state | VARCHAR | 64 |
| country_iso_cca2 | VARCHAR | 2 |
+-------------------|---------+--------+
The good part
The "Country" field works just fine. It fetches data from the JSON dataset at creation and reads/writes info from or to the DB on update/save:
// ClientCrudController.php
$countries = new Countries();
$allCountriesCodes = $countries->all()->pluck('name.common', 'cca2')->toArray();
$this->crud->addField([
'name' => 'country_iso_cca2',
'label' => 'Country',
'type' => 'select2_from_array',
'options' => $allCountriesCodes,
'allows_null' => false,
'default' => 'US',
]);
The bad (incomplete) part
// ClientCrudController.php
$this->crud->addField([
'name' => 'state',
'label' => 'State',
'type' => 'select2_from_ajax',
'entity' => 'foobar', // the method that defines the relationship in your Model
'attribute' => 'name',
'data_source' => url('api/states'),
'placeholder' => 'Select a country first...',
'dependencies' => ['country_iso_cca2'],
]);
Calling /admin/client/create will result in an error ("Call to undefined method App\Models\Client::foobar").
I understand that the error is raised because there is no model defined for States and hence no relationship. My problem is, I do not understand what the implementation is supposed to look like in a case like this where the two select fields do not represent separate entities at an ORM level.
Is it possible to implement this kind of dependency in a "backpack-native" way, without resorting to creating a custom field type?

Is there some option to create Yii2 ActiveDataProvider from query and static data?

I use ActiveDataProvider to display some data using GridView. Also I have some data retrieved from API and this is a array. For example:
$emails = [
'123' => 'john#test.io',
'234' => 'jane#test.io',
'345' => 'jake#test.io'
];
$query = new Query();
$query->select(['id', 'username'])->from('user');
$provider = new \yii\data\ActiveDataProvider([
'query' => $query,
'pagination' => [
'pageSize' => 100,
],
]);
Result of displaying this ActiveDataProvider will be something like this:
+------+--------------+
| id | username |
+------+--------------+
| 123 | John |
| 234 | Jane |
| 345 | Jake |
+------+--------------+
How can I join data from query and array to get something like this:
+------+--------------+-------------------+
| id | username | email |
+------+--------------+-------------------+
| 123 | John | john#test.io |
| 234 | Jane | jane#test.io |
| 345 | Jake | jake#test.io |
+------+--------------+-------------------+
I found the only one option - create an array from query and merge it with existing array, but it looks bad for me. Is there any other solution?
You are probably looking for this
https://www.yiiframework.com/doc/api/2.0/yii-data-arraydataprovider
An ArrayDataProvider acts in a lot of the ways the same as an ActiveDataProvider and you can use it as the base data for most of the Yii2 controls. I would get the ActiveDataProvider data, parse it, match it to what you already have by default and create an array that can be used as the base of the ArrayDataProvider.
If you are putting it into a DataGrid you can always do something like this for the email column
[
'class' => 'yii\grid\DataColumn',
'attribute' => 'email',
'format'=>'raw',
'value'=>function ($model) use ($emails) {
return $emails[$model->id];
},
],
A way , for complex or aggregated model, could be based on adding and afterFind method in your model
add the property you need and populate you value with a proper function eg:named getYourRelatedEmail()
or you could use an assigment depending the way you obatin the email array or the related values)
In your model
public $userEmail;
public function afterFind()
{
$this->userEmail = getYourRelatedEmail();
}
in this way you can acces in gridview to the model data field as common model field
In this way you could retrive all the data you need form different sources and build yuor composite model as you need ..

cakephp 3 paginate sort custom field

i try to sort "hasMany" associate
this is my code :
Advisor Modal
$this->hasMany('AdvisorNotes', [
'foreignKey' => 'id',
'sort' => [
'created' => 'DESC',
],
'joinType' => 'LEFT',
]);
Advisor Controller
public function index() {
$this->paginate = [
'contain' => [
'Branch' => [ 'BranchCity', 'Bank' ],
'AdvisorLevel',
'AdvisorRelation',
'UsersAgent',
'AdvisorNotes'
],
'sortWhitelist' => [
'BranchCity.city_name',
'Branch.name',
'Advisor.name',
'AdvisorRelation.relation',
'AdvisorLevel.level',
'Advisor.telephone',
'UsersAgent.name',
'AdvisorNotes.created',
'Bank.name',
]
];
$advisors = $this->paginate( $this->Advisor );
AdvisorNotes table
id | advisor_id | agent_id | type_id | note | created
Advisor table
id | name | image | date_of_birth | important_date | branch_id | telephone | fax | cellphone | email | description | level_id | relation_id | agent_id | agent_admin_id | created
i try to make field in the Advisor index that show the last AdvisorNote and be able to sort it.
as you can see AdvisorNotes as advisor_id in table but Advisor dont have any id of the AdvisorNotes.
thanks.

Laravel updateOrCreate - not updating correctly

I have 3 tables in my DB files, file_types and post_files and when I am saving file type first to my DB like this:
private function findOrCreateFileType($fileType)
{
return $fileType = FileType::firstOrCreate([
'name' => $fileType,
'slug' => str_slug($fileType, '-')
]);
}
Then after that I am saving a file to DB and updating 'content_files' table as well like this:
$file = File::updateOrCreate([
'cms_id' => $inventoryRemoteId,
'file_name' => $file->post_name,
'file_path' => $file->guid,
], [
'file_type_id' => $fileType->id,
'file_extension' => pathinfo($file->guid)['extension'],
'file_size' => $fileInfo['Content-Length']
]);
PostFile::updateOrCreate([
'file_id' => $file->id,
'post_id' => $contentId,
],[
'file_type_id' => $fileType->id,
]);
The problem that I have is when I am saving a post that has for example 2 files of 2 different types, for example an attachment and a feature image then it is correctly saving in to the file_types table:
ID | name
--------------------
1 | feature_image
--------------------
2 | attachment
But, then when I am saving to files table, it is not saving correctly since it is giving the last type to every file for that post:
ID | file_type_id | name
--------------------
1 | 1 | feature_image file name
--------------------
2 | 1 | attachment file name
So, since I am first saving feature-image and then attachments it is for some reason updating the file_type_id of the feature-image in the files table, as well as in the post_files table. What am I doing wrong, how can I fix this?

Cakephp 3 - Save associated belongsToMany (joinTable)

i have a question about saving a new entity with an association which is a belongsToMany relation. Just a quick introduction. I have something like a settings table and a setting_values table. The user is connected to the settings by a joinTable called users_settings. So in summary:
settings:
id | name
setting_values:
id | setting_id | name | value |
users_settings:
id | user_id | setting_id | setting_value_id
Now before the user is added I want to patch the entity of the user with all settings and the first setting_value for each setting. So that users_settings has now all settings connected to the user with the first value. But I can't get the patch or the newEntity to be work. All models are baked so this should be fine. Here's my code
$settings = $this->Settings->find('all', [
'contain' => [
'SettingValues'
]
]);
$settingsData = [];
foreach ($settings as $setting) {
$settingsData[] = [
'setting_id' => $setting->id,
'setting_value_id' => $setting->setting_values[0]->id,
];
}
$data = [
'users_settings' => $settingsData
];
$user = $this->Users->patchEntity($user, $data, [
'associated' => [
'Settings.UsersSettings'
]
]);
This is the result in the $user entity. As you can see nothing is corretly marshaled:
users_settings => [
(int) 0 => [
setting_id => (int) 1,
setting_value_id => (int) 1
],
(int) 1 => [
setting_id => (int) 2,
setting_value_id => (int) 5
]
]
Can someone give me an advice on this. Thanks
That's not how belongsToMany association data should be structured, you have to supply the target, not the join table. Additional join table data can be supplied via the special _joinData key, ie the data should look like:
$data = [
'settings' => [
[
'id' => 1,
'_joinData' => [
'setting_value_id' => 1
]
],
[
'id' => 2,
'_joinData' => [
'setting_value_id' => 5
]
]
]
];
That would populate the join table like:
+----+---------+------------+------------------+
| id | user_id | setting_id | setting_value_id |
+----+---------+------------+------------------+
| 1 | 1 | 1 | 1 |
| 2 | 1 | 2 | 5 |
+----+---------+------------+------------------+
And if you (need to) use the associated option, then make sure to specify the _joinData key too:
$user = $this->Users->patchEntity($user, $data, [
'associated' => [
'Settings._joinData'
]
]);
See also
Cookbook > Database Access & ORM > Saving Data > Saving BelongsToMany Associations
Cookbook > Database Access & ORM > Saving Data > Saving Data To The Join Table

Categories