I know this question is repeated, but trying out several of the answers of those questions has done nothing for me.
In short, I have this store method:
public function store(Request $request)
{
$selected_products = json_decode($request->selectedproducts);
$cart = new Cart();
$cartprods = CartProd::hydrate( $selected_products );
// This sums all the end costs to get a total cost
// And saves the cart so that its id is not null
$final_cost = 0;
foreach ($cartprods as $prod) {
$final_cost += $prod->cost;
}
$cart->cost = $final_cost;
$cart->user_id = Auth::user()->id;
$cart->save();
foreach ($cartprods as $prod) {
$prod->cart_id = $cart->id;
$og_product = Product::FindOrFail($prod->product_id);
$og_product->amount -= $prod->amount;
$og_product->save();
$prod->save();
dd($prod->save());
}
return redirect()->route('cart');
}
Doing the dd above shows true, but going into my database and doing select * says that its an empty set.
Here is my CartProd model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class CartProd extends Model
{
use HasFactory;
protected $table = 'cartprod';
protected $primaryKey = 'id';
protected $fillable = [
'unit_price',
'amount',
'discount',
'cost',
'cart_id',
'product_id',
];
public function cart()
{
return $this->belongsTo(Cart::class, 'cart_id');
}
public function product()
{
return $this->belongsTo(Product::class, 'product_id');
}
}
And just because it might be useful, these are the commands for the migrations of the table (they're in their own migration file, so there's no issue there):
Schema::create('cartprod', function (Blueprint $table) {
$table->id();
$table->decimal('unit_price',9,2);
$table->integer('amount');
$table->integer('discount');
$table->decimal('total_cost',9,2);
$table->timestamps();
});
Schema::table('cartprod', function (Blueprint $table) {
$table->foreignId('cart_id')->references('id')->on('cart');
});
Schema::table('cartprod', function (Blueprint $table) {
$table->foreignId('product_id')->references('id')->on('product');
});
Having searched for the answer I found several others that didn't helped me, like the $primaryKey matching the name on the database (it does), or others that didn't fit my model. Thanks a lot for your help!
Thanks to #Lyzvaleska for the suggestion! Turns out the Hydrate function was the problem, so all I had to do is replace it and create each cartprod with a foreach as such:
public function store(Request $request)
{
$selected_products = json_decode($request->selectedproducts);
$cartprods = array();
$final_cost = 0;
foreach ($selected_products as $prod) {
$final_cost += $prod->total_cost;
$selProd = new CartProd();
$selProd->unit_price = $prod->unit_price;
$selProd->amount = $prod->amount;
$selProd->discount = $prod->discount;
$selProd->total_cost = $prod->total_cost;
$selProd->cart_id = $prod->cart_id;
$selProd->product_id = $prod->product_id;
array_push($cartprods, $selProd);
}
$cart = new Cart();
$cart->cost = $final_cost;
$cart->user_id = Auth::user()->id;
$cart->save();
foreach ($cartprods as $prod) {
$prod->cart_id = $cart->id;
$og_product = Product::FindOrFail($prod->product_id);
$og_product->amount -= $prod->amount;
$og_product->save();
$prod->save();
}
return redirect()->route('cart');
}
Related
Hey im searching for a method to delete adn entry which is connected to some other with ManytoMany and belongstoMany Relations, my question is how can i get an query that it finds the relations and checks it, if there are none it should be deleted and if there are some it should not delete it.
this is my Controller:
public function index()
{
$tracks = Track::all();
$seasons = Season::all();
return view('index.track', compact('tracks', 'seasons'));
}
public function create(): \Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Contracts\Foundation\Application
{
$seasons = Season::all();
$topics = Topic::all();
$speakers = Speaker::all();
return view('create.track', compact('topics', 'seasons', 'speakers'));
}
public function store(TrackStore $request): \Illuminate\Http\RedirectResponse
{
$hashedName = Hash::make($request->file('track_data')->getClientOriginalName()) . "." . $request->file('track_data')->getClientOriginalExtension();
$request->track_data->storeAs('public/tracks', $hashedName);
$track = new Track();
$track->title = $request->track_title;
$track->description = $request->track_description;
$track->data = $hashedName;
$track->season_id = $request->season_id;
$track->save();
$track->speakers()->attach($request->input('speakers'));
$track->topics()->attach($request->input('topics'));
if($request->input('moderators')) {
$data = [];
foreach ($request->input('moderators') as $moderatorId) {
$data[$moderatorId] = ['is_moderator' => 1];
};
$track->speakers()->attach($data);
return redirect()->route('admin.trackShow');
} else {
return redirect()->route('admin.trackShow');
}
}
public function delete(Track $id): \Illuminate\Http\RedirectResponse
{
$id->delete();
return redirect()->route('admin.trackShow');
}
public function edit(Track $id)
{
return view('edit.track');
}
This is my Model:
class Track extends Model
{
use HasFactory;
protected $table = 'tracks';
protected $primaryKey = 'id';
protected $fillable = [
'title',
'description',
'data',
'season_id',
];
public function season(): BelongsTo
{
return $this->belongsTo(Season::class);
}
public function speakers(): BelongsToMany
{
return $this->belongsToMany(Speaker::class, 'speakers_tracks', 'track_id', 'speaker_id')->withPivot('is_moderator');
}
public function topics(): BelongsToMany
{
return $this->belongsToMany(Topic::class, 'topics_tracks', 'track_id', 'topic_id');
}
}
This is my migration:
Schema::create('tracks', function (Blueprint $table) {
$table->id('id');
$table->string('title');
$table->string('description');
$table->string('data');
$table->integer('season_id')->unsigned();
$table->timestamps();
$table->softDeletes();
});
As you see the Tracks are connected to many other stuff they are connected via relations. thanks in advance!
It will be easy with count()
if ($supplier->items()->count() == 0) $supplier->delete();
It is not your model. But you will get the idea.
I'm very new to Laravel (this is my first time using it) and I'm trying to store some data that I made in a post request to my api. I keep on getting a General error: 1364 Field 'question_entity_id' doesn't have a default value.
I'm trying to use Laravel's push method to save the itemBank model and all it's relationships I define below but I get the error above. I've tried manually setting foreign_key relationships like `$itemBank->question_entity_id = $questionEntity->id' but this gives me the same error. I'm specifically trying to figure out why question_entity_id isn't getting filled (I know that the error could be resolved by making the field nullable or giving question_entity_id a default value).
Here are the relevant models:
class ItemBank extends Model
{
// table name
protected $table = "item_bank";
// do no use default timestamp fields
public $timestamps = false;
// item_bank relationships to other Models/tables
public function questionEntity() {
return $this->hasOne('App\QuestionEntity', 'id', 'question_entity_id');
}
public function optionEntity() {
return $this->hasMany('App\OptionEntity', 'item_id', 'id');
}
public function tagItemRel() {
return $this->hasOne('App\TagItemRel', 'item_id', 'id');
}
}
class QuestionEntity extends Model
{
// table name
protected $table = 'question_entity';
// disable default timestamps
public $timestamps = false;
public function itemBank() {
return $this->belongsTo('App\ItemBank', 'id', 'question_entity_id');
}
}
Here is the code where I'm trying to store my data:
public function store(Request $request)
{
$data = $request->all();
$itemBank = new ItemBank();
//save question body text
$questionEntity = new QuestionEntity();
$questionEntity->question = $data['questionBody'];
$itemBank->questionEntity()->save($questionEntity);
// save correct answer
$itemBank->correct_answers = $data['correctAnswer'];
//save question options
$choices = ['A', 'B', 'C', 'D'];
//$optionEntities = [];
foreach($choices as $choice) {
$optionEntity = new OptionEntity();
$optionEntity->choice = $data['choice' . $choice];
$optionEntity->choice_label = $choice;
$optionEntity->itemBank()->associate($itemBank);
}
//$itemBank->optionEntity()->saveMany($optionEntities);
//create new ItemTag Model
$itemTag = new ItemTag();
$itemTag->tag_name = $data['topic'];
//create new TagItemRel Model
$tagItemRel = new TagItemRel();
$tagItemRel->itemTag()->save($itemTag);
$tagItemRel->itemBank()->associate($itemBank);
$itemBank->push();
return $itemBank;
}
Here are the relevant migration files:
QuestionEntity:
Schema::create('question_entity', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('question', 500);
});
ItemBank:
Schema::create('item_bank', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('question_entity_id');
$table->string('correct_answers', 1);
$table->foreign('question_entity_id')->references('id')->on('question_entity');
});
Add question_entity_id in your ItemBank model, like this.
protected $fillable = [
'question_entity_id',
];
So your ItemBank model will look like this.
class ItemBank extends Model
{
// table name
protected $table = "item_bank";
protected $fillable = [
'question_entity_id','correct_answers'
];
I'm using Lumen, trying to edit values, which is the easiest thing to do, for some reason, the updated values aren't being saved
Task.php model
public function taskUsers()
{
return $this->hasMany('App\Models\Tasks\UserTask')->where('role',1);
}
UserTask.php model contains nothing, an empty model
class UserTask extends BaseModel { }
Migrations
class CreateTasksTable extends Migration
{
protected $table = 'tasks';
protected $app_table = true;
public function up()
{
Schema::create($this->getTable(), function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->dateTime('submit_date');
$table->dateTime('closed_date')->nullable();
$table->dateTime('due_date')->nullable();
$table->tinyInteger('is_done')->nullable()->default(0);
$table->integer('domain_id')->unsigned()->nullable();
$table->foreign('domain_id')->references('id')
->on(self::getTableName('domains'))->onDelete('cascade');
$table->bigInteger('created_by')->unsigned()->nullable();
$table->foreign('created_by')->references('id')
->on(self::getTableName('auth_users', false))->onDelete('cascade');
$table->bigInteger('closed_by')->unsigned()->nullable();
$table->foreign('closed_by')->references('id')
->on(self::getTableName('auth_users', false))->onDelete('cascade');
$table->timestamps();
});
}
public function down()
{
Schema::drop($this->getTable());
}
}
and
class CreateTaskUsersTable extends Migration
{
protected $table = 'task_user';
protected $app_table = true;
public function up()
{
Schema::create($this->getTable(), function (Blueprint $table) {
$table->increments('id');
$table->integer('task_id')->unsigned()->nullable();
$table->foreign('task_id')->references('id')
->on(self::getTableName('tasks'))
->onDelete('cascade');
$table->bigInteger('user_id')->unsigned()->nullable();
$table->foreign('user_id')->references('id')
->on(self::getTableName('auth_users', false))
->onDelete('cascade');
$table->integer('role');
});
}
public function down()
{
Schema::drop($this->getTable());
}
}
The edit action for example is so simple, if I just want to edit the title, that won't work, without even editing the rest.
class EditTaskAction extends BaseAction
{
protected $verbs = array('POST');
protected $private = true;
protected $inputRules = [
'domain_id' => 'required',
'task_id' => 'required',
'title' => '',
'due_date' => '',
'assignee_id' => '',
'is_done' => '',
'role' => ''
];
public function execute()
{
$title = $this->request->get('title');
$dueDate = $this->request->get('due_date');
$assigneeId = $this->request->get('assignee_id');
$taskId = $this->request->get('task_id');
$isDone = $this->request->get('is_done');
$role = $this->request->get('role');
$userId = \Auth::id();
$domainId = $this->request->get('domain_id');
\DB::beginTransaction();
try {
$task = Task::where('id', $taskId)
->where("domain_id", $domainId) ->first();
$userTask = UserTask::where('task_id', $taskId)->first();
if (isset($title) && !empty($title)) {
$task->title = $title;
}
if (isset($dueDate) && !empty($dueDate)) {
$task->due_date = $dueDate;
}
if (isset($assigneeId) && !empty($assigneeId)) {
$userTask->user_id = $userId;
}
if (isset($role) && !empty($role)) {
if ($role == TaskUserRole::ASSIGNEE) {
$userTask->role = $role;
}
}
if (isset($isDone) && !empty($isDone) ) {
if ($isDone == 0) {
$task->closed_by = null;
$task->closed_date = null;
$task->is_done = 0;
} else if ($isDone == 1) {
$task->closed_by = $userId;
$task->closed_date = Carbon::now();
$task->is_done = 1;
}
}
$task->save();
$userTask->save();
return $this->response->statusOk();
} catch (\Exception $exception) {
\DB::rollBack();
\Log::error($exception);
$this->response->addErrorDialog(self::SOMETHING_WENT_WRONG);
return $this->response->statusFail(self::SOMETHING_WENT_WRONG);
}
\DB::commit();
}
}
Basically all I'm doing
$task = Task::find($taskId); // I tried that too
$task->title = 'something';
$task->save();
It's not working
I think the problem is with your transaction. You're starting it with \DB::beginTransaction(); But the \DB::commit() (to save your changes to the database) will never be run, because you do Return-Statements before, like return $this->response->statusOk();
You could try to save your response to a variable and return it after the \DB::commit();
class EditTaskAction extends BaseAction
{
// ...
public function execute()
{
// ...
$response = null;
\DB::beginTransaction();
try {
// ...
$task->save();
$userTask->save();
$response = $this->response->statusOk();
} catch (\Exception $exception) {
// ...
$response = $this->response->statusFail(self::SOMETHING_WENT_WRONG);
}
\DB::commit();
return $response;
}
}
i thinks the problem in your model do you put your data stored in fillable
Did you set the guarded property on the model? You can completely disable guarding by setting it to an empty array.
protected $guarded = [];
// or check this:
protected $fillable = [...];
Otherwise you might find some error in the logs.
class PostController extends Controller{
public $grupID = 1;
public function store(Request $request)
{
$post = new Post();
$post->GroupID = 'POST-' . $this->grupID;
$post->save();
return response()->json($post);
$this->grupID++;
}
}
Database Structur
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->integer('PostTypeID');
$table->string('GroupID', 100)->nullable();
$table->timestamps();
});
}
I want to make the groupID auto increment, but it always return 'POST-1'.
Try this one, you need to get the last value in your DB,
class PostController extends Controller{
public function store(Request $request)
{
$lastValue = DB::table('posts')->orderBy('GroupID', 'desc')->first();
$post = new Post();
$post->GroupID = 'POST-' . $lastValue->GroupID + 1 ;
$post->save();
return response()->json($post);
}
}
Hope this help :)
in your database migration file
$table->increments('grupID');
and it's automatically increment.
class PostController extends Controller{
public function store(Request $request)
{
$last = DB::table('posts')->last();
$post = new Post();
if ($last) {
$part = explode('-', $last->GroupID);
$post->GroupID = $part[0] . '-' . ($part[1] + 1);
} else {
$post->GroupID = 'POST-1';
}
$post->save();
return response()->json($post);
}
}
When you use a return statement, the execution stops, so your increment never happens. Put the return statement at the end.
class PostController extends Controller{
public function store(Request $request)
{
$groupID = Post::pluck('GroupID')->last();
$post = new Post();
$post->GroupID = 'POST-' . $groupID + 1;
$post->save();
return response()->json($post);
}
}
$groupID = Post::pluck('GroupID')->last();
This gives you the last groupID from the column table (ordered asc by ID).
$post->GroupID = 'POST-' . $groupID + 1;
This increment the value before saving it in the table.
This is the method in the controller:
public function buyConfirm($ad_id)
{
$ad = Ad::find($ad_id);
$sale = new Sale;
$sale->ad_id = $ad->id;
$sale->seller_id = $ad->user->id;
$sale->buyer_id = \Auth::user()->id;
$sale->save();
$x = new Notification;
$x->ad_id = $ad->id;
$x->user_id = $ad->user->id;
$x->type = 'bought';
$x->view = 0;
$x->save();
$ad->delete();
return \Redirect::route('buyContact',$sale->id)->with('message', 'Done');
}
Laravel insert the first row without problems, but the second register not, in the new Notification dont insert if $ad->id but if a send a harcode value like '4' the insert is successfully, what happend whit this?
The Notification migration:
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateNotificationsTable extends Migration
{
public function up()
{
Schema::create('notifications', function (Blueprint $table) {
$table->increments('id');
$table->string('type');
$table->integer('user_id')->unsigned();
$table->integer('ad_id')->unsigned();
$table->boolean('view');
$table->timestamps();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->foreign('ad_id')->references('id')->on('ads')->onDelete('cascade');
});
}
public function down()
{
Schema::drop('notifications');
}
}
This is the model:
<?php namespace Telovendogdl;
use Illuminate\Database\Eloquent\Model;
class Notification extends Model
{
protected $table = 'notifications';
protected $fillable = ['type','ad_id','user_id','view'];
public function user()
{
return $this->belongsTo('App\User');
}
public function ad()
{
return $this->belongsTo('App\Ad');
}
}
I believe your onDelete('cascade') is messing you up.
Right after creating the Notification, you call $ad->delete(). But your migration contains:
$table->foreign('ad_id')->references('id')->on('ads')->onDelete('cascade');
This means that when an ad is deleted, the notification is also deleted.