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.
Related
[SOLVED]
/***
The parent-children relationship works fine. But there was a code i wrote several weeks ago that prevent me to update the progress value.
***/
I have a project that has similar functionality to trello (kanban)
There are 3 models which are projects, TaskList (columns), Tasks (cards).
a project has many columns
a column has many tasks
a task has many
subtasks (the subtask refer to the model itself)
each model has a column named progress. This column must be updated when the children are updated. The progress is calculated by averaging the progress of all cards.
Models :
Project.php
class Project extends Model
{
use HasFactory;
protected $table = 'projects';
public $timestamps = true;
protected $fillable = [
'id','title', 'description', 'actual_start', 'actual_end',
'start', 'end','progress'
];
public function updateProgress(){
$sum=0;
if(count($this->columns)){
for ($i = 0; $i < count($this->columns); $i++) {
$list = $this->columns[$i];
if($list->progress==null){
$list->progress=0;
}
$sum+=$list->progress;
}
$progress=$sum/count($this->columns);
$this->progress=round($progress);
$this->save();
}
return $this->progress;
}
public function scopeExclude($query, $value = [])
{
return $query->select(array_diff($this->fillable, (array) $value));
}
public function lists(){
return $this->hasMany(TaskList::class,'projects_id');
}
TaskList.php
class TaskList extends Model
{
protected $table = 'lists';
protected $fillable = [ 'title', 'position', 'projects_id', 'start', 'end', 'actual_start', 'actual_end','progress' ];
public static function boot() {
parent::boot();
static::saved(function($list){
$list->project->updateProgress();
});
}
public function updateProgress(){
$tes=[];
if(count($this->cards)){
$sum=0;
for ($i = 0; $i < count($this->cards); $i++) {
$task = $this->cards[$i];
if($task->progress==null){
$task->progress=0;
}
$sum+=$task->progress;
$tes[]=['id'=>$task->id,'progress'=>$task->progress,$task->cards];
}
$progress=$sum/count($this->cards);
$this->progress=round($progress);
$this->save();
}
return ['id'=>$this->id,'progress'=>$this->progress,'cards'=>$this->cards];
}
public function cards(){
return $this->hasMany(Task::class,'lists_id');
}
}
Task.php
class Task extends Model
{
use HasFactory;
protected $table = 'tasks';
public $timestamps = true;
protected $fillable = [
'id','users_id', 'title', 'description', 'complete', 'end', 'start',
'actual_start', 'actual_end', 'start_label', 'end_label',
'progress', 'is_subtask', 'lists_id','parent_task_id'
];
protected $casts = [
'progress' => 'double',
];
public static function boot() {
parent::boot();
static::saving(function($task){
if(!empty($task->start) && !empty($task->end)){
$start = Carbon::parse($task->start);
$end = Carbon::parse($task->end);
$days= $start->diffInDays($end);
$task->days=$days+1;
}
if(!empty($task->actual_start) && !empty($task->actual_end)){
$actual_start = Carbon::parse($task->actual_start);
$actual_end = Carbon::parse($task->actual_end);
$work_days= $actual_start->diffInDays($actual_end);
$task->work_days=$work_days+1;
}
// This part was the problem
if($task->parentTask){
if($task->actual_end){
$task->progress=100;
}else{
$task->progress=0;
}
}else{
if($task->actual_end){
$task->progress=100;
}else{
$task->progress=0;
}
}
if($task->parentTask){
if($task->actual_end){
$task->progress=100;
}else{
$task->progress=0;
}
}else{
if($task->actual_end){
$task->progress=100;
}else{
$task->progress=0;
}
}
//------------------------
if($task->progress==100){
$task->complete=true;
}
});
static::saved(function($task){
//is a subtask
if($task->parentTask){
// dd('subtask',$task->id,$task->complete,$task->progress,$task->parentTask,$task->list);
$task->parentTask->updateProgress();
}else{
// dd('parent task',$task->id,$task->complete,$task->progress,$task->parentTask,$task->list);
$task->list->updateProgress();
// dd('list ',$task->list->updateProgress());
}
});
static::deleting(function($task) {
foreach ($task->members as $i => $member) {
$member->delete();
}
foreach ($task->cards as $k => $subtask) {
$subtask->delete();
}
$task->tags()->detach();
$task->task_members()->detach();
});
}
public function updateProgress(){
if(count($this->cards)){
$valuePerSubtask=100/count($this->cards);
$completeSubtaskCounter=0;
for ($i = 0; $i < count($this->cards); $i++) {
$subtask = $this->cards[$i];
if($subtask->complete){
$completeSubtaskCounter++;
}
}
$progress=$completeSubtaskCounter*$valuePerSubtask;
$this->progress=$progress;
$this->save();
return [$this->progress,$progress];
}
}
public function scopeExclude($query, $value = [])
{
return $query->select(array_diff($this->fillable, (array) $value));
}
public function parentTask(){
return $this->belongsTo(Task::class,'parent_task_id');
}
public function list(){
return $this->belongsTo(TaskList::class,'lists_id');
}
}
I can't update the parent task from the children. As you can see in Task.php model, I have a updateProgress() that return [$this->progress, $progress]; after i call $this->save(). I already have $this->progress=$progress before i save it. But $this->progress still show the same result.
[![the first item is $this->progress, the second one is $progress][1]][1]
[1]: https://i.stack.imgur.com/RS2mq.png
i tried override touch() and place updateProgress() inside it. But still doesn't show the expected result.
Any advice for a better approach?
Am I missing something?
A solution also could be:
Create an observer on task.
php artisan make:observer TaskObserver
and then in the observer.
class UserObserver
{
//SOME METHODS
public function updated(Task $task)
{
/* Important, this will be done with all tasks on update in the tree
like Task->task->task etc... unless you put some extra logic. But
this is the general idea
*/
#search if parent
if ($task->parent_task_id !== null) {
//run progress
$task->parentTask->updateProgress()
}
}
}
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 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');
}
I am using databaseeder to store the name of controller in the permissions table but i didnot why i am getting error.This table have a relation with roles table using belongsToMany relation.
Here is my Role.php
public function permissions()
{
return $this->belongsToMany(Permission::class)->withTimeStamps();
}
Here is my Permission.php
protected $fillable=['id','name','controller'];
public function roles()
{
return $this->belongsToMany(Role::class)->withTimeStamps();
}
And Here is my databaseSeeder.php
$superrole= Role::create([
'name'=>'super admin',
]);
$permission_ids = [];
$route_name = [];
$controllers = [];
foreach (Route::getRoutes()->getRoutes() as $route)
{
$action = $route->getAction();
if (array_key_exists('as', $action)) {
$route_name = $action['as'];
}
if (array_key_exists('uses', $action)) {
$controllers = $action['uses'];
}
$permission_check = Permission::whereIn('name' , $route_name)
->whereIn('controller' , $controllers)->first();
if(!$permission_check)
{
$permission = new Permission;
$permission->controller = $controllers;
$permission->name = $route_name;
$permission->save();
$permission_ids[] = $permission->id;
}
}
$superrole->permissions()->attach($permission_ids);
But when i try to run the db:seed iam getting this error]1
Here is the dd($controllers)
and dd($route_name)
I'm trying to add a description to my thumbnail but it won't update in my database.
Can you guys see why?
The only thumb_description won't update.
Fillables are filled. When i did $content->save() it will return true.
Controller:
public function detail(Request $request, $id)
{
$content = Content_blocks::find($id);
if ($request->isMethod('post')) {
if ($request->hasFile('image')) {
$folder = 'uploads';
$name = $request->image->getClientOriginalName();
$store = $request->image->store($folder, 'public');
$file = pathinfo(Storage::url($store));
$thumb_description = $request->input('thumb_description');
$thumbnail = new Thumbnail();
$thumbnail->name = $file['filename'];
$thumbnail->extenstion = $file['extension'];
$thumbnail->path = $folder;
$thumbnail->thumb_description = $thumb_description;
$thumbnail->save();
$content->thumbnail_id = $thumbnail->id;
}
$content->title = $request->input('title');
$content->description = $request->input('description');
$content->link = $request->input('link');
$content->linkname = $request->input('linkname');
$content->order = $request->input('order');
$content->contentcategory_id = $request->input('categorie');
$content->thumbnail->thumb_description = $request->input('thumb_description');
if ($request->input('ontkoppel') === 'deletion') {
Thumbnail::find($content->thumbnail_id)->delete();
}
// dd($content->thumbnail->thumb_description);
$content->save();
return redirect('admin/content/webcategorie/homepage/contentblocks/' . $content->content_id);
}
Model
<?php
namespace App\Models;
use Illuminate\Support\Facades\Storage;
class Thumbnail extends Model
{
protected $fillable = [
"thumb_description",
"name",
"path",
"extenstion"
];
protected $table = 'thumbnail';
public function content()
{
return $this->belongsTo(Content::class);
}
public static function getFile($id)
{
$thumbnail = self::find($id);
if ($thumbnail === null) {
return null;
}
$url = sprintf('%s/%s.%s', $thumbnail->path, $thumbnail->name, $thumbnail->extenstion);
return Storage::disk('public')->url($url);
}
public static function getDescription($id)
{
$thumbnail = self::find($id);
if ($thumbnail === null) {
return null;
}
$description = $thumbnail->thumb_description;
return $description;
}
}
Migration
*/
public function up()
{
Schema::create('thumbnail', function (Blueprint $table) {
$table->increments('id');
$table->string('name', 255);
$table->string('path', 150);
$table->string('extenstion', 10);
$table->text('thumb_description');
$table->timestamps();
});
}
Post in chrome dev tools
------WebKitFormBoundaryfun4SMk5TA604OZE
Content-Disposition: form-data; name="thumb_description"
bruyanga
$content->save(); will only save the attributes on $content and not its relationships.
Try $content->push(); instead which should cascade through the loaded relationships and save all related models as well.
https://laravel.com/api/5.6/Illuminate/Database/Eloquent/Model.html#method_push