in laravel 8 model factory gives array error - php

i'am laravel beginner and want to create a model factory. RegulationFactory
i use factories and database seeder for make them.
and when i want to seed it , gives error :
ErrorException : Array to string conversion
can you help me for fix it?
this is my regulation migration :
public function up()
{
Schema::create('regulations', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id');
$table->string('country');
$table->string('photo');
$table->string('short_description');
$table->longText('description');
$table->string('population');
$table->string('area');
$table->string('internet_penetration');
$table->string('national_currency');
$table->string('goverment');
$table->string('president');
$table->string('capital');
$table->string('language');
$table->float('economic_growth');
$table->string('dgtl_curr_lgs')
->comment('Legislation of digital currencies');
$table->string('dgtl_curr_tax')
->comment('Tax on digital currencies');
$table->string('dgtl_curr_pymt')
->comment('Payment status through digital currency');
$table->string('dgtl_curr_ntiol')
->comment('National Digital Currency');
$table->string('ICO');
$table->string('crpto_antimon_rules')
->comment('has Anti-money laundering rules for crypto or not');
$table->tinyInteger('status')
->comment('status is 1 when a regulation is active and it is 0 otherwise.')->nullable();
$table->foreign('user_id')->references('id')->on('users');
$table->rememberToken();
$table->softDeletes();
$table->timestamps();
});
}
this is my regulation factory :
public function definition()
{
$users = User::pluck('id');
return [
'user_id'=>\App\Models\User::inRandomOrder()->first()->id,
'country'=>$this->faker->country,
'photo'=>$this->faker->text(10),
'description'=>$this->faker->sentences(50),
'short_description'=>$this->faker->sentence(50),
'population'=>$this->faker->numerify('########'),
'area'=>$this->faker->numerify('########'),
'internet_penetration'=>$this->faker->numerify('#########'),
'national_currency'=>$this->faker->word,
'goverment'=>$this->faker->words,
'president'=>$this->faker->name,
'capital'=>$this->faker->city,
'language'=>$this->faker->words,
'economic_growth'=>$this->faker->numerify('#'),
'dgtl_curr_lgs'=>$this->faker->sentence(1),
'dgtl_curr_tax'=>$this->faker->words,
'dgtl_curr_pymt'=>$this->faker->words,
'dgtl_curr_ntiol'=>$this->faker->words,
'ICO'=>$this->faker->word,
'crpto_antimon_rules'=>$this->faker->word,
];
}
and my regulation model :
class Regulation extends Model
{
use HasFactory;
protected $fillable = [
'user_id' ,
'country' ,
'photo',
'short_description' ,
'description',
'area',
'internet_penetration',
'national_currency',
'goverment',
'president',
'capital',
'language',
'economic_growth',
'dgtl_curr_lgs',
'dgtl_curr_tax',
'dgtl_curr_pymt',
'dgtl_curr_ntiol',
'ICO',
'crpto_antimon_rules',
];
public function users(){
return $this->belongsTo(User::class);
}
}
where is my mistake? thank you for your help :}

Your mistake is you are using $this->faker->words. Should be $this->faker->word (without "s")
see: Faker Provider Lorem

As you have used $this->faker->words. Here, $this->faker->words(5) expects a number of words. So, you need to set the number of words by passing value or you can use only "$this->faker->word"

Related

Combine 2 eloquent result and update them

I have two tables that have relation each other :
1st table products migration :
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
2nd table discount migration :
Schema::create('discounts', function (Blueprint $table) {
$table->id();
$table->foreignId('product_id');
$table->double('rate', 8, 2); // rates between 0.05 ~ 0.2
$table->foreignId('period_id');
$table->timestamps();
});
Product model :
/**
* Get the product associated with discount.
*/
public function discounts()
{
return $this->hasMany(Discount::class);
}
Discount model :
/**
* Get the discount associated with product.
*/
public function product()
{
return $this->belongsTo(Product::class);
}
What i've tried so far is a bit silly :
$productWithoutDiscount = Product::doesntHave('discounts')
->where([
['section', Session::get('section-budget')],
['status', 'PREPARED']
])->get();
$productWithDiscount = Product::with('discount')->whereHas('discounts', function ($query) {
$query->where('rate' ,'>', 0.05);
})->get();
$productAll = $productWithoutDiscount->merge($productWithDiscount);
Above code works, however, i also need to update them, that wont happened as the merged eloqunet instance will be converted to collection (which doesn't have access to update() method)
How can i get both the product which don't have discount AND product which have discount with above 0.05 rate and update them ?
Update 1
So i follow #Salvon's advice to use union, so these my following code atm :
$productAll = Product::with('discount')->whereHas('discounts', function ($query) {
$query->where('rate' ,'>', 0.05);
})->union(Product::doesntHave('discounts')
->where([
['section', Session::get('section-budget')],
['status', 'PREPARED']
]));
Then another problem came out, because when i execute the update method like so :
try {
$productAll->update([
'period_id' => Session::get('period');
]);
return response()->json([
'message' => 'Data successfully updated.'
], 201);
} catch (\Throwable $th) {
return response()->json([
'message' => $th->getMessage()
], 500);
}
nothing was updated and not even any error come out,
Already check the protected $fillable on my model and the 'period_id' is there.
how can I solved this ?
Update 2
Weird after i cahge the order of query like so :
$productAll = Product::doesntHave('discounts')->where([
['section', Session::get('section-budget')],
['status', 'PREPARED']
])->union(Product::with('discount')->whereHas('discounts', function ($query) {
$query->where('rate' ,'>', 0.05);
}));
The update() method works. What is the cause ?

Laravel Getting value of another table using foreign key on Blade

I have two models Batch and Notices. The foreign key is correctly formed and data is saved in the database. Now I can't show the data on my listing blade.
Notice Migration:
Schema::create('notices', function (Blueprint $table) {
$table->id();
$table->string('noticeTitle');
$table->string('noticeDesc');
$table->string('file')->nullable();
$table->unsignedBigInteger('batch_id');
$table->foreign('batch_id')->references('id')->on('batches');
$table->timestamps();
});
Batch Migration:
Schema::create('batches', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
Data dump from db is:
"id" => 1
"noticeTitle" => "Quae ea est temporib"
"noticeDesc" => "<p>sa</p>"
"file" => null
"batch_id" => 2
"created_at" => "2020-07-27 16:09:52"
"updated_at" => "2020-07-27 16:09:52"
]
Notice model
public function batches()
{
return $this->belongsTo(Batch::class);
}
Batch Model
public function notice()
{
return $this->hasMany(Notice::class);
}
Notice controller
public function index(){
$notices = Notice::all();
return view('admin.notice.list')
->with('notices', $notices);
}
public function store(Request $request)
{
$this->validate($request, [
'noticeTitle' => 'required',
'noticeDesc' => 'required',
]);
$notice = new Notice;
$notice->noticeTitle = $request->input('noticeTitle');
$notice->noticeDesc = $request->input('noticeDesc');
$notice->batch_id = $request->input('targetedGroup');
if($request->hasFile('file')) {
$noticeTitle = $request->input('noticeTitle');
$filename = $request->file->getClientOriginalName();
$request->file->storeAs('public/noticeFile/additionalFiles', $noticeTitle.'_'.$filename);
$path = $noticeTitle.'_'.$filename;
$notice->file = $path;
}
try{
$notice->save();
Session::flash('success', 'Notice Saved');
return redirect()->route('notice.index');
}
catch (\Throwable $th){
Session::flash('danger', 'Something went wrong');
return redirect()->route('notice.index');
}
}
Now I want to get batch name from batch_id
First, you might want to change the function names of your relationships. Your notice has only one batch, so it should be public function batch() and a batch has several notices, so public function notices().
You can acces your relationships like any attribute, so in your blade:
#foreach($notices as $notice)
#php $batch = $notice->batch; #endphp
{{$batch->name}}
#endforeach
Or even shorter (if you don't plan on using the related batch for anything else)
#foreach($notices as $notice)
{{$notice->batch->name}}
#endforeach
This is all explained in the Laravel documentation: https://laravel.com/docs/7.x/eloquent-relationships

Laravel - Data mismatch from eager load

I am creating factories and saving the page model to the film model so its film to page one-to-many,
i've followed the docs but when im trying to save the models to each other i am getting this error
General error: 20 datatype mismatch (SQL: insert into "pages" ("id", "page_url", "film_id", "updated_at", "created_at") values (591d61cb-3090-3945-b920-ba797245cb97, http://larson.com/, bd3bab38-f8be-4674-ae5d-15e8f6b6172a, 2019-11-15 11:23:02, 2019-11-15 11:23:02))
These are the classes i am working with
Film migration
public function up()
{
Schema::create('films', function (Blueprint $table) {
$table->uuid('id')->primary();
$table->string('name');
$table->string('description');
$table->timestamps();
});
}
Pages migration
public function up()
{
Schema::create('pages', function (Blueprint $table) {
$table->bigIncrements('id');
$table->uuid('film_id')->nullable();
$table->string('page_url')->nullable();
$table->timestamps();
});
}
PagesFactory
$factory->define(Pages::class, function (Faker $faker) {
return [
'id' => $faker->uuid,
'page_url' => $faker->url,
'film_id' => factory(\App\Models\Film::class)->create()->id
];
Pages model
public function film(): BelongsTo
{
return $this->belongsTo(Film::class);
}
FilmController
*/
public function show(string $id)
{
$film = Film::with([
'pages',
'languages',
'categories',
])->findOrFail($id);
return $film;
FilmControllerTest
public function getFilmTest()
{
$film = factory(Film::class)->create();
$language = Language::where('id', 'en')->where('name', 'English')->first();
$categories = Category::where('main-cat', 'Science')->where('sub-cat', 'Fiction')->first();
$film->pages()->save(factory(Page::class)->create());
$film->languages()->attach($language->id);
$film->categories()->attach($categories->id);
$response = $this->json('GET', '/film/' . $film->id)
->assertStatus(200);
$response
->assertJson(['id' => $guestProfile->id])
->assertJson(['name' => $film->description])
->assertJson(['languages' => $film->languages->toArray()])
->assertJson(['categories' => $film->categories->toArray()])
}
when i comment out this line from the test it works fine $film->pages()->save(factory(Page::class)->create());
im abit lost on why im having this issue trying to save the models so the pages becomes part of the response... can i get some help/example please :D
The id of your pages table is set to a bigIncrements (UNSIGNED BIGINT), but in your PagesFactory you are trying to store a uuid.
$factory->define(Pages::class, function (Faker $faker) {
return [
'id' => $faker->uuid,
'page_url' => $faker->url,
'film_id' => factory(\App\Models\Film::class)->create()->id
];
Remove 'id' => $faker->uuid, from the factory, you don't have to set an auto incrementing field.
Another option (depending on the design you have in mind) is to change the migration of the pages table and set the id column to $table->uuid('id')->primary();
try using the make() method, as in:
$film->pages()->save(factory(Page::class)->make());

Unknown column 'notifiable_id' in 'field list' - Laravel Notifications

I have been trying to understand why is this error appearing. This is my first time with Laravel's notification system and I'm getting the error above. I have been following the docummentation on Laravel's website but I can't seem to get the grip of this error.
JobDenied
public function via($notifiable)
{
return ['database'];
}
public function toDatabase($notifiable)
{
return [
'deniedTime' => Carbon::now()
];
}
public function toArray($notifiable)
{
return [
//
];
}
Notification tables
// Generate using php artisan notifications:table
Schema::create('notifications', function (Blueprint $table) {
$table->uuid('id')->primary();
$table->string('type');
$table->morphs('php ');
$table->text('data');
$table->timestamp('read_at')->nullable();
$table->timestamps();
});
Invoking the notificaton
$sendToUser = User::find(2);
$sendToUser->notify(new JobDenied());
I have tried adding the prefix notifiable_ in the notifications table but I ended up getting a new error Unknown column 'id' in 'field list' note the prefix notifiable_ missing.
I'm using Laravel 5.4.35
You need to change $table->morphs('php '); in your notifications migration to $table->morphs('notifiable');
Credits goes directly to: https://laracasts.com/discuss/channels/laravel/unknown-column-id-in-field-list-laravel-notifications #sutherland
For Laravel 8, this was corrected but I still experience this error when I used Model binding to retrieve the model.
public function example(Model $model){ $model->notify(new NotificationFile());}
Was able to solve it by retrieving the model normally.
public function example($slug){ $model = Model::findOrFail($slug);
$model->notify(new NotificationFile());}

Extend Laravel Schema Builder create function

I've searched in the docs and fiddled with the Laravel code but found nothing about it. I'm using Laravel 5.1.
I want to know if I can extend the Schema::create function or do something in terms of reverse migration. I want to recover the fields and types set during migration and output them to a json file for each migration file (there are many).
This file will be used in angular formly.
This way I can generate everything during the migration command.
I believe repeating the code for each migration is not the best approach. Any ideas?
class CreatePlanTypesTable extends Migration
{
public function up()
{
Schema::create('plan_types', function (Blueprint $table)
{
$table->increments('id');
$table->string('name');
$table->string('slug');
$table->dateTime('created_at');
$table->dateTime('updated_at');
// ---- dont want to repeat for each migration file -----
$json = [];
$columns = $table->getColumns();
foreach($columns as $column)
{
$json[] = [
'key' => $column['name'],
'type' => $column['type'],
'templateOptions' => [
'label' => '',
'placeholder' => ''
]
];
}
file_put_contents('tablefile.json', json_encode($json));
// -------------------
});
}
...

Categories