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.
Related
I'm developing an API with Laravel. In one of the endpoint I'm accessing, some fields are showing a null value, but it should have some information.
Note the "addicionais_descricao" and "valor" fields, both always come with null values when I include them in the attributeitems array, but if I leave it at the initial level, the data is presented, but it doesn't solve my case, because I need this information with the attribute items:
enter image description here
This is where the endpoint calls, I make the query in the "Attribute" table, which has a relationship with the "Attributeitems" table, while the "attributeitems" table is linked to "Attribute" and "product".
public function show($id)
{
$atributos = Atributo::query('atributo')
->select(
'atributo.id',
'atributo.atrdescricao',
'atributoitens.atributo_id',
'atributoitens.produto_id',
'produto.prodescricao',
'produto.provalor'
)
->leftJoin('atributoitens', 'atributo.id', '=', 'atributoitens.atributo_id')
->leftJoin('produto', 'produto.id', '=', 'atributoitens.produto_id')
->where('atributo.id', '=', $id)
->get()->unique('id');
return AtributoResource::collection($atributos);
}
Resource Atributo:
public function toArray($request)
{
return [
'id' => $this->id,
'descricao' => $this->atrdescricao,
'atributoitens' => AtributoitensResource::collection($this->atributoitens),
];
}
Resource Atributo Itens:
public function toArray($request)
{
return [
'id' => $this->id,
'atributo' => $this->atributo_id,
'produtos' => $this->produto_id,
'adicionais_descricao' => $this->prodescricao,
'valor' => $this->provalor
];
}
What is the correct procedure for this situation?
Take this example as a reference :
Controller
$data = $shop->products()
->whereStatus(true)
->where('product_shop.active', true)
->where('product_shop.quantity', '>=', $this->min_product_qty)
->paginate(50);
return (new ProductCollection($data))
->response()
->setStatusCode(200);
ProductCollection
public function toArray($request)
{
return [
'data' => $this->collection
->map(function($product) use ($request) {
return (new ProductResource($product))->toArray($request);
}),
'brand' => $this->when($request->brand, $request->brand)
];
}
ProductResource
public function toArray($request)
{
return [
'type' => 'product',
'id' => (string) $this->id,
'attributes' => [
'uuid' => $this->uuid,
'name' => $this->name,
'slug' => $this->slug,
'description' => $this->description,
'thumb_path' => $this->thumb_path,
'cover_path' => $this->cover_path,
],
'relationships' => [
'brand' => $this->brand
]
];
}
Something like this should help you do what you want. I cant exactly do it for you. by the way why you are not using Eloquent, something like
Attribute::where(...)->with(['relation_1', 'products'])->get();
public function toArray($request)
{
return [
'id' => $this->id,
'attributes' => [...],
'products' => $this->collection
->map(function($this->product) use ($request) {
return (new ProductResource($product))->toArray($request);
}),
];
}
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,
];
}
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"
}
In Laravel I have relation:
class Address extends Model
{
protected $fillable = [
'street', 'city', 'post_code', 'country', 'state',
];
public function companies() {
return $this->hasMany('App\Company');
}
}
class Company extends Model
{
protected $fillable = [
'name', 'nip', 'email', 'phone', 'address_id'
];
public function address() {
return $this->belongsTo('App\Address');
}
}
and in CompaniesController.php I want to do update tables. My code looks like this:
public function update(Request $request, $id)
{
Company::where('id', $id)->update([
'name' => $request->name,
'email' => $request->email,
'phone' => $request->phone,
'nip' => $request->nip,
]);
}
How to also update the address associated with this company?
If the ID is your primary key, you should use find instead of where, as the former will guarantee that you only retrieve one row.
You can then query the relationship of your Company model, using the following code:
$company = Company::find($id);
$company->update([
'name' => $request->name,
'email' => $request->email,
'phone' => $request->phone,
'nip' => $request->nip,
]);
$company->address()->update([
'street' => 'street value',
'city' => 'city value',
'post_code' => 'post_code value',
'country' => 'country value',
'state' => 'state value',
]);
Please refer to the laravel docs
I have the following tables for my many to many relationship: soldhomestests, tasks and soldhomestest_task (as the pivot).
My soldhomestests table has already been populated with data. How do I get my soldhomestest_task pivot table to populate with data upon the creation of a new task that meets conditions in my soldhomestest table? In my example, I want to store the relationship data when the following conditions are met:
'tasks.city' = 'soldhomestests.city'
'tasks.address' = 'soldhomestests.address'
I can't seem to find any documentation on how to proceed with this?
MODELS:
class Task extends Model
{
protected $fillable = [
'address', 'city', 'state',
];
public function user()
{
return $this->belongsTo(User::class);
}
public function soldhomestests()
{
return $this->belongsToMany('App\Soldhomestest');
}
}
class Soldhomestest extends Model
{
public function tasks()
{
return $this->belongsToMany('App\Task');
}
}
CONTROLLER:
public function store(Request $request)
{
$this->validate($request, [
'address' => 'required|max:255',
'city' => 'required|max:255',
'state' => 'required|max:255',
]);
$request->user()->tasks()->create([
'address' => $request->address,
'city' => $request->city,
'state' => $request->state,
]);
return redirect()->route('settings.index');
}
Don't believe this is the Laravel way but I modified my controller to create an array of IDs using the where condition:
public function store(Request $request)
{
$this->validate($request, [
'address' => 'required|max:255',
'city' => 'required|max:255',
'state' => 'required|max:255',
]);
$newtask = $request->user()->tasks()->create([
'address' => $request->address,
'city' => $request->city,
'state' => $request->state,
]);
$condition = DB::table('soldhomestests')->where([
['soldhomestests.address', '=', $request->address],
['soldhomestests.city', '=', $request->city],
])->pluck('id');
$lastid = $newtask->id;
$tasksoldhome = Task::find($lastid);
$tasksoldhome->soldhomestests()->sync($condition);
return redirect()->route('settings.index');
}
Using eloquent, you can do this way.
$task=new Task();
$task->city=$request->city;
$task->address=$request->address;
$task->save();
$soldhometests=Soldhometest::all();
foreach($soldhometests as $soldhometest)
{
if($task->city==$soldhometest->city && $task->address==$soldhometest->address)
{
$soldhometest_task=new SoldhometestTask(); // pivot model
$soldhometest_task->task_id=$task->id;
$soldhometest_task->soldhometest_id=$soldhometest->id;
$soldhometest_task->save();
}
}