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"
}
Related
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.
Im building CRUD for my application in Laravel 9. I defined some fields in my database as NOT NULL. Those values will be completed by code at the time a new user is created.
The first field Im dealing with is 'creado' (same as 'created at' in english) field (and I dont want to use built in timestamp)
User model:
public $timestamps = false;
protected $fillable = [
'username',
'password',
'apellidos',
'nombres',
'tipoDocumento',
'nroDocumento',
'cuit',
'cuil',
'fechaNacimiento',
'sexo',
'domicilio',
'domicilioNro',
'domicilioPiso',
'domicilioDepto',
'localidad',
'codigoPostal',
'telefonoFijo',
'telefonoCelular',
'telefonoAlt',
'email',
'creado', //This is the value
];
protected $hidden = [
'password',
'password_repeat', //This value is still being displayed in error msg...
'remember_token',
];
protected $casts = [
'creado' => 'datetime', //Dont think its necessary
];
public function setPasswordAttribute($password)
{
$this->attributes['password'] = bcrypt($password);
}
public function setCreadoAttribute()
{
//This method never get called...
$this->attributes['creado'] = date("Y-m-d H:i:s");
}
RegisterRequest:
public function rules()
{
return [
'username' => 'required|unique:clientes,username',
'password' => 'required|min:8',
'password_repeat' => 'required|same:password',
'apellidos' => 'required',
'nombres' => 'required',
'fechaNacimiento' => 'required',
'sexo' => 'required',
'tipoDocumento' => 'required',
'nroDocumento' => 'required|unique:clientes,nroDocumento',
'cuil' => 'nullable|min:11|max:11',
'cuit' => 'nullable|min:11|max:11',
'domicilio' => 'required',
'domicilioNro' => 'required',
'localidad' => 'required',
'codigoPostal' => 'required',
'telefonoCelular' => 'required',
'email' => 'required|unique:clientes,email',
'creado' => 'nullable|date',
];
}
Controller:
public function register(RegisterRequest $request)
{
$cliente = Clientes::create($request->validated());
return redirect("login")->with("success","Bla Bla Bla");
}
In view, all fields are present, except 'creado'. If I add input type text named creado, it works. Else the field its not included in the query. I dont know why its not working when I marked it as nullable.
$casts array and setCreado can be removed.
Then, you can use an accessor, in your model:
protected function creado(): Attribute
{
return Attribute::make(
get: fn ($value) => date("Y-m-d H:i:s"),
);
}
Mas info ;) Accessors
Importante this:
This method name should correspond to the "camel case" representation of the true underlying model attribute / database column when applicable.
Finally, I was able to fix this using this approach:
In ClientsController
public function register(RegisterRequest $request)
{
$cliente = new Cliente;
$cliente = Cliente::make($request->validated());
$cliente->setCreadoAttribute();
$cliente->save();
return redirect("login")->with("success","Cuenta creada exitosamente");
}
In Client model:
public function setCreadoAttribute()
{
$this->attributes['creado'] = date("Y-m-d H:i:s");
}
Im not really sure if this is the best way or the best practice to accomplish what I was needing, but for now it works.
From the docs
If you need to customize the names of the columns used to store the timestamps, you may define CREATED_AT and UPDATED_AT constants on your model:
<?php
class Flight extends Model
{
const CREATED_AT = 'creation_date';
const UPDATED_AT = 'updated_date';
}
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,
];
}
Migration
In my migration, I have following passed to the database
$table->enum('product_name', ['chocolate', 'Candy','biscuits', 'Berry']);
$table->string('description');
$table->string('product_no');
$table->timestamps();
in my model I have this below the fillable and a function to select a choice.
protected $fillable =[
'product_no','description'
];
protected $product_name = ['chocolate', 'Candy','biscuits', 'Berry'];
public function getProduct_name()
{
return $this->product_name;
}
The problem is I don't know how to handle this in controller and Postman. It is not displaying any error
public function store(Request $request)
{
$this->validate($request, [
'product_no' => 'nullable|product_no',
'description' => 'required|string',
]);
$product = new Product();
$product->product_no = $request->product_no;
$product->description = $request->description;
$product->product_name = $request->$model->getProduct_name();
if (auth()->user()->products()->save($product))
return response()->json([
'success' => true,
'data' => $product->toArray()
]);
else
return response()->json([
'success' => false,
'message' => 'product could not be added'
], 500);
}
What I intend to achieve is to create a front-end in Angular with a drop down to select the product_name (from the list hard-coded) and description and product_no are fillable. However from Postman, I just entered the values for the three fields i.e. product_name, description and product_no
It seems you forgot to replace method and variable names when you copy the votes code
$product = new Product();
$product->product_no = $request->product_no;
$product->description = $request->description;
$product->product_name = $request->$model->getProduct_name();
if (auth()->user()->votes()->save($vote))
--------------------^^^^^^^-------^^^^^--
return response()->json([
'success' => true,
'data' => $product->toArray()
]);
That should be
if (auth()->user()->products()->save($product))
Also there is another field (product_name) that you're trying to save but it's not fillable.
protected $fillable =[
'product_no','description', 'product_name'
];
And also, you may want to consider that using same pattern when naming your variables and methods. You can say getProductName or get_product_name instead of getProduct_name.
its very suspect. I have an array with values. But when I use a create method on the model the values are NULL.
When I use the update function all values are right.
protected function createProduct(array $data)
{
// dd($data['category_id']);
return Product::create([
'category_id' => $data['category_id'],
'manufacturer_id' => $data['manufacturer_id'],
'sku' => $data['sku'],
'collection' => $data['collection'],
'name' => $data['name'],
'name_en' => $data['name_en'],
'sku_supplier' => $data['sku_supplier'],
'order' => $data['order'],
]);
//
create() is using mass assignment feature so you need to add all values to the $fillable property first which should be added to Product model:
class Product extends Model
{
protected $fillable = ['category_id', 'manufacturer_id', 'sku', 'collection', 'name', 'name_en', 'sku_supplier', 'order'];
Also, you can just do this to create new product:
return Product::create($data);