Can't call model method in toSearchableArray array when created via factory - laravel

I am trying to get a model factory to work, the main model Venue the following:
Place which is a hasOne relation
Type which has a belongsTo relation
On top of that, place has a function called full_address, that returns a comma separated string.
The Venue has a toSearchableArray() to send custom data to Algolia, when I run the factory create method I get:
PHP Error: Call to a member function full_address() on null in app/Venue.php on line 57
This is the venue Model
class Venue extends Model
{
use Searchable;
public function toSearchableArray()
{
$type = $this->type()->first();
$place = $this->place()->first();
return [ 'name' => $this->name,
'type' => $type['name'],
'type_id' => $type['id'],
'venue_id' => $this->id,
'background_image' =>$type['background_file_name'],
'full_address' => $place->full_address(),
'slug' => $this->slug_field,
'_geoloc' =>
[ 'lat' => (float)$this->latitude,
'lng' => (float)$this->longitude
]
];
}
public function place()
{
return $this->hasOne('App\Place');
}
public function type()
{
return $this->belongsTo('App\Type');
}
}
And these are the model factories
$factory->define(App\Venue::class, function (Faker\Generator $faker) {
return [
'name' => $faker->name,
'phoneNumber' => $faker->word,
'latitude' => $faker->latitude,
'longitude' => $faker->longitude,
'LatLong' => $faker->word,
'website' => $faker->word,
'type' => $faker->word,
'place_id' => function () {
return factory(App\Place::class)->create()->id;
},
'status' => $faker->word,
'slug_field' => $faker->word,
'type_id' => function () {
return factory(App\Type::class)->create()->id;
},
];
});
$factory->define(App\Place::class, function (Faker\Generator $faker) {
return [
'place_id' => $faker->randomNumber(),
'administrative_area_level_2' => $faker->word,
'administrative_area_level_1' => $faker->word,
'country' => $faker->country,
'postal_town' => $faker->word,
'postal_code_prefix' => $faker->word,
'postal_code' => $faker->word,
'route' => $faker->word,
'locality' => $faker->word,
'premise' => $faker->word,
'street_number' => $faker->word,
'neighborhood' => $faker->word,
'point_of_interest' => $faker->word,
'natural_feature' => $faker->word,
'administrative_area_level_3' => $faker->word,
'postal_code_suffix' => $faker->word,
'sublocality_level_1' => $faker->word,
'subpremise' => $faker->word,
'sublocality_level_5' => $faker->word,
'sublocality_level_4' => $faker->word,
'sublocality_level_2' => $faker->word,
'sublocality_level_3' => $faker->word,
'administrative_area_level_4' => $faker->word,
'colloquial_area' => $faker->word,
'long' => '123',
'lat' => '123',
];
});
$factory->define(App\Type::class, function (Faker\Generator $faker) {
return [
'name' => $faker->name,
'marker_file_name' => $faker->word,
'background_file_name' => $faker->word,
'description' => $faker->word,
'ShortName' => $faker->word,
];
});
what do I need to do in order to get a reference to the place that is associated with the venue.
Thanks

Related

How to override the select2 action that disables subfield options selected in a previous subfield in Backpack for Laravel?

Controller (field definition):
$this->crud->addField([
'name' => 'precios',
'type' => "relationship",
'pivotSelect' => [
'ajax' => true,
'inline_create' => [ 'entity' => 'precio' ],
'data_source' => backpack_url('presupuesto/fetch/precio'),
'minimum_input_length' => 0,
'wrapper' => [
'class' => 'col-md-3 order-2'
],
'attributes' => [
'required' => 'required',
],
'dependencies' => ['categoria_precio_id']
],
'subfields' => [
[
'name' => 'categoria_precio_id',
'type' => 'relationship',
'label' => 'Categoría',
'wrapper' => [
'class' => 'form-group col-md-2 order-1',
],
'dependencies' => ['tipo'],
'ajax' => true,
'data_source' => backpack_url('presupuesto/fetch/categoria-precio'),
'minimum_input_length' => 0
],
[
'name' => 'costo',
'type' => 'text',
'label' => 'Costo Unitario',
'wrapper' => [
'class' => 'form-group col-md-1 order-3',
],
],
[
'name' => 'cantidad',
'type' => 'text',
'wrapper' => [
'class' => 'form-group col-md-1 order-4',
],
],
[
'name' => 'duracion',
'type' => 'text',
'wrapper' => [
'class' => 'form-group col-md-2 order-5',
]
],
[
'name' => 'costo_final',
'type' => 'text',
'label' => 'Costo',
'wrapper' => [
'class' => 'form-group col-md-1 order-6 costo_final',
],
'attributes' => array('readonly' => 'readonly', 'disabled' => 'disabled')
],
],
'tab' => "Precios",
'force_delete' => true]);
My Form capture
When I tried to select an option that I selected previously it does not allow me. For example, in the image "animación 2d" (ID:82).
First I have in my table "precio_presupuesto"
precio_id (PK)
presupuesto_id (PK)
costo
...
created_at
updated_at
And I change that for:
id (PK)
precio_id (FK)
presupuest_id (FK)
costo
...
created_at
updated_at
In my model I had:
public function precios()
{
return $this->belongsToMany(\App\Models\Precio::class)->withPivot('costo', 'cantidad', 'duracion', 'categoria_precio_id', 'costo_final')->withTimestamps();
}
And I change that for:
public function precios()
{
return $this->belongsToMany(\App\Models\Precio::class,'precio_presupuesto', 'presupuesto_id','precio_id', 'id')->withPivot('costo', 'cantidad', 'duracion', 'categoria_precio_id', 'costo_final')->withTimestamps();
}
I'm new to Laravel and Backpack, but I think my definition is fine, I just don't know how to tell Backpack to allow adding two elements with repeated "price_id" and "presupuesto_id", this because there will be cases where you can change the "cantidad" field or the "costo" field for the same combination (precio_id, presupuesto_id).
In other words I just want the "Select2" subfields not to disable previously selected options.
My model
I have tried changing the definition of my models again. Create a class for the pivot table following the documentation and example of:
doc
example
Presupuesto Model
class Presupuesto extends Model implements Auditable{
public function precio_presupuesto(){
return $this->hasMany(PrecioPresupuesto::class, 'presupuesto_id');
}
public function precios(){
return $this->belongsToMany(\App\Models\Precio::class)->using(\App\Models\PrecioPresupuesto::class)->
withPivot('costo', 'cantidad', 'duracion', 'categoria_precio_id', 'costo_final')->withTimestamps();
}
}
Precio Model:
class Precio extends Model{
public function precio_presupuesto()
{
return $this->hasMany(PrecioPresupuesto::class, 'precio_id');
}
public function presupuestos()
{
// return $this->belongsToMany(\App\Models\Presupuesto::class);
return $this->belongsToMany(\App\Models\Presupuesto::class)->using(\App\Models\PrecioPresupuesto::class)->
withPivot('costo', 'cantidad', 'duracion', 'categoria_precio_id', 'costo_final')->withTimestamps();
}}
Pivot Model:
class PrecioPresupuesto extends Pivot{
public function presupuesto(){
return $this->belongsTo(Presupuesto::class, 'presupuesto_id');
}
public function precio(){
return $this->belongsTo(Precio::class, 'precio_id');
}}
Does Backpack allow me to save several pairs of elements like in the image pivot table precio_presupuesto? what is what I need? because it currently does not allow me.

yajra/laravel-datatables filterColumn doesnt work

Page loading correctly and every things work fine while bringing datas. Now I want to filter them but FilterColumn() method doesnt even work. When I tried filter() method it's working but then I won't get $keywords variable. I am missing something while querying leads ?
if (request()->ajax()) {
$leads = Lead::with('country','agent','detail')->orderBy('id','DESC');
$leads->where(function($q) use ($user){
if ($user->hasRole('agent') && !$user->hasRole('admin') && !$user->hasRole('lead')){ //agent isem
$q->where('agent_id',$user->id)
->orWhere('agent_id',null);
}
});
return DataTables::of($leads)->
addColumn('edit_button', function ($lead) {
$link = route('leads.edit',$lead->id);
return ' Edit ';
})->
filterColumn('edit_button', function ($query, $keyword) {
dd($keyword);
return $query->whereHas('patient', function ($query) use ($keyword) {
$query->whereRaw("CONCAT( name, ' ', surname ) like ?", ["%$keyword%"]);
});
})->rawColumns(['edit_button','phone','detail.conversion_notes'])->
toJson();
}
$tableColumn = [
['data' => 'edit_button', 'name' => 'edit_button', 'title' => 'Edit', 'searchable' => false],
['data' => 'full_name', 'name' => 'full_name', 'title' => 'Full Name'],
['data' => 'phone', 'name' => 'phone', 'title' => 'Phone'],
['data' => 'email', 'name' => 'email', 'title' => 'Email'],
['data' => 'country.name', 'name' => 'country.name', 'title' => 'Country'],
['data' => 'agent.name', 'name' => 'agent.name', 'title' => 'Agent'],
['data' => 'treatment', 'name' => 'treatment', 'title' => 'Treatment'],
['data' => 'find_us', 'name' => 'find_us', 'title' => 'Find Us'],
['data' => 'form_type', 'name' => 'form_type', 'title' => 'Form','visible' => false],
['data' => 'social_account', 'name' => 'social_account', 'title' => 'Sosyal Medya'],
['data' => 'created_at', 'name' => 'created_at', 'title' => 'Created At'],
['data' => 'detail.conversion_notes', 'name' => 'detail.conversion_notes', 'title' => 'Primary Notes'],
];
$html = $builder->columns($tableColumn)->parameters([
"pageLength" => 25,
"lengthMenu" => [[10, 25, 50, 100, -1], [10, 25, 50, 100, "All"]],
'dom' => 'Bfrtip',
'columnDefs' => [
['width' => '2%', 'targets' => 0],
['width' => '7%', 'targets' => 1],
'buttons' => [
'pageLength',
[
'extend' => 'colvis',
'collectionLayout' => 'fixed two-column',
'columns' => ':not(.noVis)'
]
]
]);

Search in Laravel Datatables

In my datatables, the search function works only on the name column. The name column ist different that the others. It means, the name column gives the value of the database back, while the others gives a value back with the function add column
In the column array there are the following values:
´´´
protected function getColumns()
{
return [
'status',
'name' => [
'title' => 'Name',
'orderable' => true,
'searchable' => true
],
'location' => [
'title' => 'Standort',
],
'department' => [
'title' => 'Abteilung',
'orderable' => true,
'searchable' => true
],
'division' => [
'title' => 'Bereich',
'orderable' => true,
'searchable' => true
],
'leader' => [
'title' => 'Verantwortlicher',
'orderable' => true,
'searchable' => true
],
'start_date' => [
'title' => 'Startdatum',
'searchable'=> true,
],
'end_date' => [
'title' => 'Enddatum',
'searchable'=> true
]
];
}
```
Why it doesn't search on all columns? What i have to do?
Try to search by using this code.
return Datatables::of($tasks)
->filter(function ($query) use ($request) {
$title = $request->title;
if (isset($title) && !empty($title)) {
$query->where('title', 'like', '%'.$title.'%');
}
})->make(true);
OR
return Datatables::of($tasks)
->filterColumn('title', function($query, $value) {
$query->whereRaw("title like ?", ["%{$value}%"]);
})->make(true);

required_if works incorrect

I use the following validation rule:
'email' => 'required_if:phone-register,false|email|max:255|unique:users',
And my incoming data are:
array:6 [▼
"_token" => "xPGUfppYirlLmSezTQduKZV4NXUAqf3I5DhrSJTZ"
"email" => null
"phone" => "514033390"
"phone-register" => "true"
"password" => "1234567"
"password_confirmation" => "1234567"
]
Despite on I have incoming email as null, the validation for email still works. Why, if I set required_if:phone-register,false
Full code of validation:
return Validator::make($data, [
'email' => 'required_if:phone-register,"false"|email|max:255|unique:users',
'password' => 'required|min:6|confirmed',
'phone-register' => 'required|boolean',
'phone' => 'required_if:phone-register,"true"|numeric|min:6|max:15'
]);
Now I have:
protected function validator(array $data)
{
$v = Validator::make($data, [
'password' => 'required|min:6|confirmed',
'phone-register' => 'required',
'phone' => 'required_unless:phone-register,true|numeric|min:6'
]);
$v->sometimes('email', 'required|email|max:255|unique:users', function ($input) {
return $input->phone-register === "false";
});
}
You can add rules conditionally:
$v = Validator::(....);
$v->sometimes('email', 'required|email|max:255|unique:users', function ($input) {
return $input->phone-register === "false";
});

These credentials do not match our records

I have an app with laravel in which, I have different users and different roles. I insert some users, roles, role_user, permission and permission_role in my DB using seeder but, when I try to login using email and password already recorded in DB, I got : These credentials do not match our records.
this is UserTableSeeder :
public function run()
{
//
$user = [
[
'name' => 'admin',
'email' => 'admin#mail.co',
'password' => 'passwordadmin'
],
[
'name' => 'president',
'email' => 'President#mail.co',
'password' => 'passwordpresident'
],
[
'name' => 'utilisateur1',
'email' => 'utilisateur1#mail.co',
'password' => 'passworduser'
],
[
'name' => 'utilisateur2',
'email' => 'utilisateur2#mail.co',
'password' => 'passworduser'
]
];
foreach ($user as $key => $value) {
User::create($value);
}
}
RoleTableSeeder :
public function run()
{
//
$role = [
[
'name' => 'admin',
'display_name' => 'Administrateur',
'description' => 'Administrateur du système'
],
[
'name' => 'president',
'display_name' => 'Président',
'description' => 'President de la commune'
],
[
'name' => 'utilisateur_normal',
'display_name' => 'membre du conseil',
'description' => 'membre du conseil'
]
];
foreach ($role as $key => $value) {
Role::create($value);
}
}
RoleUserTableSeeder :
public function run()
{
//
DB::table( 'role_user' )->insert([
[ 'user_id' => 6, 'role_id' => 4 ],
[ 'user_id' => 7, 'role_id' => 5 ],
[ 'user_id' => 8, 'role_id' => 6 ],
[ 'user_id' => 9 , 'role_id' => 6 ],
]);
}
Models I have : User, Role, Permission.
Any idea please ?
It looks you are not hashing your passwords into your database, you need to use bycript:
public function run()
{
//
$user = [
[
'name' => 'admin',
'email' => 'admin#mail.co',
'password' => bcrypt('passwordadmin')
],
[
'name' => 'president',
'email' => 'President#mail.co',
'password' => bcrypt('passwordpresident')
],
[
'name' => 'utilisateur1',
'email' => 'utilisateur1#mail.co',
'password' => bcrypt('passworduser')
],
[
'name' => 'utilisateur2',
'email' => 'utilisateur2#mail.co',
'password' => bcrypt('passworduser')
]
];
foreach ($user as $key => $value) {
User::create($value);
}
}
You can see more seeder examples on the oficial seeder Laravel documentation.
As Troyer said, you need to hash them with bcrypt. Laravel provides a handy wrapper with \Hash::make($str).
It is extremely bad practice to have your passwords in plaintext.
You need to run your seeder like this:
public function run()
{
$users = [
[
'name' => 'admin',
'email' => 'admin#mail.co',
'password' => \Hash::make('passwordadmin') // Hash them in order to make use of \Auth library (and more importantly, in order not to be a dick to your users)
],
[
'name' => 'president',
'email' => 'President#mail.co',
'password' => \Hash::make('passwordpresident')
],
[
'name' => 'utilisateur1',
'email' => 'utilisateur1#mail.co',
'password' => \Hash::make('passworduser')
],
[
'name' => 'utilisateur2',
'email' => 'utilisateur2#mail.co',
'password' => \Hash::make('passworduser')
]
];
User::create($users); // Import them with 1 query for performance
}

Resources