Laravel 8 factories - laravel

Can someone tell me how can I make a factory with relationships etc...
I have a post table with 2 foreign keys: user_id and category_id
I need to generate dummy data but I don't know how to do it.
I have tried to make categories first then to do something with posts and users but did not work.
PostFactory:
public function definition()
{
$title = $this->faker->sentence;
$slug = Str::slug($title);
return [
'title' => $title,
'slug' => $slug,
'image' => $this->faker->imageUrl(900, 300),
'content' => $this->faker->text(300),
];
}
CategoryFactory:
public function definition()
{
$category = $this->faker->words(2, true);
$slug = Str::slug($category);
return [
'category' => $category,
'slug' => $slug
];
}
And user factory is just default one :)

You can check if you have enough records, and query the DB to find a random User and Category to use on each Post. But if there not enough records (20 Users and 7 Categories), create a new one.
PostFactory:
public function definition()
{
$title = $this->faker->sentence;
$slug = Str::slug($title);
$user = User::count() >= 20 ? User::inRandomOrder()->first()->id: User::factory();
$category = Category::count() >= 7 ? Category::inRandomOrder()->first()->id: Category::factory();
return [
'title' => $title,
'slug' => $slug,
'image' => $this->faker->imageUrl(900, 300),
'content' => $this->faker->text(300),
'user_id' => $user,
'category_id' => $category,
];
}

Related

How to get from request->value one value at a time inside foreach loop

Hello i have this code in laravel controller and i get an error for a single value:
public function store(Request $request)
{
$values = [];
$request->validate([
'order_number' => 'required',
'client_id' => 'required|exists:clients,id',
'description' => 'required',
'products' => 'required|exists:products,id',
'amount' => 'required',
]);
$order = Order::create($request->all());
foreach ($request->products as $product) {
$values[] = [
'order_id' => $order->id,
'product_id' => $product,
'amount' => $request->amount,
];
$amount = Product::find($product);
$total_value = $request->amount + $amount->amount; //the error happens here
$amount->update(['amount' => $total_value]);
}
$order->products()->attach($values);
return redirect('/')->with('msg', 'Order Saved successfully!');
}
All the values come except the $request->amount that comes as array and not as a single value in a row. This is the error i get:
Unsupported operand types: array + string
This is the product model:
protected $fillable = [
'name',
'price',
'amount',
];
public function orders()
{
return $this->belongsToMany(Order::class);
}
And this is dd($request->amount);
Assuming that $request->amount is directly related to $request->products with the index then you would either need to combine products and amount before you send the request or iterate over products with the index.
foreach ($request->products as $index => $product) {
$values[] = [
'order_id' => $order->id,
'product_id' => $product,
'amount' => $request->amount[$index], //Reference via index
];
$amount = Product::find($product);
$total_value = $request->amount[$index] + $amount->amount; //Also here
}
}

how to update key/value database with laravel?

I'm just learning laravel. I want update key / value in database with laravel api but not work.
My products model is one to many with ProductMeta and many to many with contents model.
My Models
class Product extends Model
{
use HasFactory;
protected $guarded = [];
public function productMeta()
{
return $this->hasMany(ProductMeta::class);
}
public function content()
{
return $this->belongsToMany(Content::class, 'product_contents')->withTimestamps();
}
}
class ProductMeta extends Model
{
use HasFactory;
protected $guarded = [];
public function products()
{
return $this->belongsTo(Product::class);
}
}
class Content extends Model
{
use HasFactory;
protected $guarded= [];
public function product()
{
return $this->belongsToMany(Product::class, 'product_contents');
}
Controller
public function update(Request $request, $id)
{
$product = Product::findOrFail($id);
DB::table('product_metas')
->upsert(
[
[
'product_id' => $product->id,
'key' => 'name',
'value' => $request->name,
],
[
'product_id' => $product->id,
'key' => 'price',
'value' => $request->name,
],
[
'product_id' => $product->id,
'key' => 'amount',
'value' => $request->name,
],
],
['product_id','key'],
['value']
);
return \response()->json([], 204);
}
Table Structure
API parameter
I tried with update and updateOrcreate and updateOrInsert and upsert methods.
just in upsert method writed database but inserted new data.not updated.
In your case, you should use updateOrCreate() instead of upsert.
Product::updateOrCreate([
'product_id' => $id,
'name' => $request->name,
'price' => $request->price,
'amount' => $request->amount
]);
or
Product::upsert([
[
'product_id' => $id,
'name' => $request->name,
'price' => $request->price,
'amount' => $request->amount
]
], ['product_id'], ['name', 'price', 'amount']);
In addition your problem is your table name is not matching with your structure table name. In your controller DB::table('product_metas') should be DB::table('products_meta').
my problem solved this way:
ProductMeta::query()->where('product_id', $id)->upsert([
['product_id' => $id, 'key' => 'name', 'value' => $request->name],
['product_id' => $id, 'key' => 'price', 'value' => $request->price],
['product_id' => $id, 'key' => 'amount', 'value' => $request->amount]],
['product_id'], ['value']);
$contentRecord = Product::find($id);
$contentRecord->content()->update(['path'=>$request->path]);
return response()->json([], 204);
I forget use query() method for ProductMeta and added $table->unique(['product_id', 'key']); to product meta migration.
**products relation one to many with product Meta
And Many to many with content.

Store notifications data with saveMany Contents

So what I am trying to do is store notifications to the database with Notifiable, but I have a saveMany contents and I don't know how to declare the data in the notifications. getting a null from what I've declared like the picture below
this is my saveMany store
$post = new Post;
$post->user_id = Auth::guard('webcontrol')->user()->id;
$post->lob = $request->lob;
$post->type = 'post';
$post->category_id = $request->category_id;
$post->is_published = $request->is_published;
$post->published_at = ($request->published_at) ? $request->published_at : Carbon::now();
$post->metas = '{}';
$post->save();
$post->contents()->saveMany([
new PostContent([
'lang' => 'id',
'slug' => str_slug($request->contents['id']['title'], '-'),
'title' => $request->contents['id']['title'],
'body' => $request->contents['id']['body'],
'image' => $request->contents['id']['image'],
'tag' => $request->contents['id']['tag'],
'metas' => serialize($request->contents['id']['metas']),
]),
new PostContent([
'lang' => 'en',
'slug' => str_slug($request->contents['en']['title'], '-'),
'title' => $request->contents['en']['title'],
'body' => $request->contents['en']['body'],
'image' => $request->contents['en']['image'],
'tag' => $request->contents['en']['tag'],
'metas' => serialize($request->contents['en']['metas']),
])
]);
Notification::send($user, new OneSignalNotification($post));
dd('done');
this is my Notification
class OneSignalNotification extends Notification
{
use Queueable;
public $post;
public function __construct($post)
{
$this->post = $post;
}
public function via($notifiable)
{
return ['database'];
}
public function toDatabase($notifiable)
{
return [
'body' => $this->post['body'], //this is where i confused how to declare the saveMany contents so its not returning null
];
}
}
So I'm not sure what you're trying to achieve but the issue is with the fact that you want to retrieve the body from the post, but the way I see it, the $post doesn't have a body property. The PostContent seems to have the body property, but the problem is that you saved many PostContent to the same $post, so therefore there are multiple body properties, one for each PostContent. So that's why I would recommend use the first() method to get the first PostContent from $post and then return it. If you want to return all the body property, you would have to get all of them and add them into an array or a string, or whatever you want. I hope this makes sense.
You should try using this:
$post = new Post;
$post->user_id = Auth::guard('webcontrol')->user()->id;
$post->lob = $request->lob;
$post->type = 'post';
$post->category_id = $request->category_id;
$post->is_published = $request->is_published;
$post->published_at = ($request->published_at) ? $request->published_at : Carbon::now();
$post->metas = '{}';
$post->save();
$post->contents()->saveMany([
new PostContent([
'lang' => 'id',
'slug' => str_slug($request->contents['id']['title'], '-'),
'title' => $request->contents['id']['title'],
'body' => $request->contents['id']['body'],
'image' => $request->contents['id']['image'],
'tag' => $request->contents['id']['tag'],
'metas' => serialize($request->contents['id']['metas']),
]),
new PostContent([
'lang' => 'en',
'slug' => str_slug($request->contents['en']['title'], '-'),
'title' => $request->contents['en']['title'],
'body' => $request->contents['en']['body'],
'image' => $request->contents['en']['image'],
'tag' => $request->contents['en']['tag'],
'metas' => serialize($request->contents['en']['metas']),
])
]);
Notification::send($user, new OneSignalNotification($post->fresh()));
dd('done');
And then inside the Notification, like I said, we take the first PostContent from the $post and get it's body property:
class OneSignalNotification extends Notification
{
use Queueable;
public $post;
public function __construct($post)
{
$this->post = $post;
}
public function via($notifiable)
{
return ['database'];
}
public function toDatabase($notifiable)
{
return [
'body' => $this->contents()->first()->body,
];
}
}

Laravel update eloquent not updating the record

I am using Laravel eloquent to update the record. The problem is the update method returns the integer equal to number of records should be updated but this update is not being reflected in database.
I inserted some records to check there is no database mismatch.
I am even using fillable method and defined every column into it.
Here is my code.
Modal
protected $fillable = [
'id',
'user_id',
'ticket_no',
'partner_id',
'partner_user_name',
'partner_user_email',
'partner_user_contact',
'contacted_for_id',
'issue_type_id',
'comm_mode_id',
'opened_by_id',
'assigned_to_id',
'team_id',
'priority_id',
'opened_date',
'tat_id',
'resolved_date',
'status_id',
'description',
];
Controller
public function update(Request $request)
{
$validators = Validator::make($request->all(), [
'assigned_to_id' => 'required',
'team_id' => 'required',
'resolve_date' => 'required',
'status_id' => 'required',
'description' => 'required',
]);
if ($validators->fails()) {
$data['result'] = false;
$data['messages'] = $validators->errors()->first();
return json_encode($data);
}
$assigned_to_id = $request->assigned_to_id;
$team_id = $request->team_id;
$resolve_date = $request->resolve_date;
$status_id = $request->status_id;
$description = $request->description;
$ticket_row_id = $request->ticket_row_id;
$updated = TICKET_TRACKER::where('id', $ticket_row_id)
->update(
['assigned_to_id' => $assigned_to_id],
['team_id' => $team_id],
['resolve_date' => $resolve_date],
['status_id' => $status_id],
['description' => $description]
);
}
I am not getting any error that's the most frustrated thing.
In order to make your model to be updated change:
$updated = TICKET_TRACKER::where('id', $ticket_row_id)
->update(
['assigned_to_id' => $assigned_to_id],
['team_id' => $team_id],
['resolve_date' => $resolve_date],
['status_id' => $status_id],
['description' => $description]
);
By:
$updated = TICKET_TRACKER::where('id', $ticket_row_id)
->update([
'assigned_to_id' => $assigned_to_id,
'team_id' => $team_id,
'resolve_date' => $resolve_date,
'status_id' => $status_id,
'description' => $description
]);
In fact you need to have only one array with keys and values in order to view your model updated.
[EDIT 1]
As said in the comments in Laravel you need to take care about naming conventions,
If the name of the model is TicketTracker, the name of the table should be plural. So it will be ticket_trackers.
or if you want to have a custom name for your table you can configure in your model the $table property as follows:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class TicketTracker extends Model
{
protected $table = "other_table_name"
}

why my updateOrInsert doesn't work laravel

I use updateOrInsert to avoid duplicate data, why doesn't the Update function work and always insert data?
foreach($datas as $data){
DB::table('users')->updateOrInsert([
'user_connect_id' => $user->connect_id,
'description' => $data['description'],
'created_by' => $login->name,
'modified_by' => $login->name,
'created_at' => Carbon::now(),
]);
}
Check out [updateOrInsert] this documentation (https://laravel.com/api/6.x/Illuminate/Database/Query/Builder.html#method_updateOrInsert). You need two parameters. One is the matching attributes (i.e., the attributes you would use to identify your record in case it exists), the other is your array (the new values you wish to insert or update the record with).
updateOrInsert(array $attributes, array $values = [])
Example
DB::table('users')->updateOrInsert(
[
'user_connect_id' => $user->connect_id
],
[
'user_connect_id' => $user->connect_id,
'description' => $data['description'],
'created_by' => $login->name,
'modified_by' => $login->name,
'created_at' => Carbon::now(),
]);
There are two arguments in updateOrInsert method.The updateOrInsert method accepts two arguments: an array of conditions by which to find the record, and an array of column and value pairs containing the columns to be updated.
For e.g :
DB::table('users')
->updateOrInsert(
['email' => 'john#example.com', 'name' => 'John'],
['votes' => '2']
);
Check this link for syntax : Laravel Doc
// Inseart code
public function create()
{
return view('admin.category.create');
}
public function store(Request $request)
{
$this->validate($request,[
'name' => 'required'
]);
$category = new Category();
$category->name = $request->name;
$category->slug = str_slug($request->name);
$category->save();
Toastr::success('Category Successfully Saved','Success');
return redirect()->route('admin.category.index');
}
// Update code
public function edit($id)
{
$category =Category::find($id);
return view('admin.category.edit',compact('category'));
}
public function update(Request $request, $id)
{
$this->validate($request,[
'name' => 'required|unique:categories'
]);
$category = Category::find($id);
$category->name = $request->name;
$category->slug = str_slug($request->name);
$category->save();
Toastr::success('Category Successfully Updated','Success');
return redirect()->route('admin.category.index');
}

Resources