I get a the below error when I try to update the modal text after a search performed
select * from [test] where [test].[id] in (?)
\vendor\laravel\framework\src\Illuminate\Database\Connection.php:703
I have added a primary key name in the model that is different. See the model class:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Test extends Model
{
use HasFactory;
/**
* The primary key associated with the table.
*
* #var string
*/
protected $primaryKey = 'testId';
/**
* Indicates if the model's ID is auto-incrementing.
*
* #var bool
*/
public $incrementing = false;
/**
* The data type of the auto-incrementing ID.
*
* #var string
*/
protected $keyType = 'string';
protected $connection = 'sqlsrv2';
protected $table = "test";
}
Here is the livewire class:
<?php
namespace App\Http\Livewire;
use App\Models\TestSubItems;
use App\Models\Test;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Livewire\Component;
class TestApp extends Component
{
use AuthorizesRequests;
public $search = '';
public $items = null;
public $subItems = null;
public $message = '';
public $warning = false;
public function render()
{
return view('livewire.bin-app');
}
public function search()
{
$this->items = null;
$this->subItems = null;
if ($this->search) {
$this->items = Test::where('ItemNo', $this->search)->get();
if (!$this->items->isEmpty()) {
$this->warning = false;
$this->message = '';
$this->subItems = TestSubItems::where('ItemNo', $this->search)->get();
}
if ($this->items->isEmpty()) {
$this->message = 'Not found';
}
}
}
}
Blade file:
<div>
<div class="grid grid-cols-1 gap-4 p-4">
<div>
<label for="search" class="text-right">Item Code: </label>
<input wire:model="search" autofocus="autofocus"
class="block appearance-none w-full bg-gray-200 border border-gray-200 text-gray-700 py-3 px-4 pr-8 rounded leading-tight focus:outline-none focus:bg-white focus:border-gray-500"
id=" search"
/>
</div>
#if ($message != '')
<div class="mb-5 mt-5 bg-red-50 rounded-md py-4 px-4">
<p class="font-bold text-green-500">
{{ $message }}
</p>
</div>
#endif
<div>
<button wire:click="search()" class="btn btn-primary">Search</button>
</div>
</div>
#if (isset($items))
#if (!$items->isEmpty())
<div class="grid grid-cols-1 gap-4 p-4">
#foreach($items as $item)
<h2 class="md:text-3xl text-xs"><span class="font-bold">Code:</span>
{{ $item->code }}
</h2>
#endforeach
</div>
#endif
#endif
#if (isset($subItems))
#if (!$subItems->isEmpty())
<table class="table w-full">
<thead>
<th class="border-2 border-gray-50">
Item No
</th>
<th class="border-2 border-gray-50">
Type
</th>
</thead>
<tbody>
#foreach($subItems as $item)
<tr>
<td class="border-2 border-gray-50">
{{ $item->itemNo }}
</td>
<td class="border-2 border-gray-50">
{{ $item->type }}
</td>
</tr>
#endforeach
</table>
#endif
#endif
</div>
This only happens after the initial search. I think it is related to the Model some way but not sure how.
Any help would be great to solve this.
I run your code, I only added to the TestSubItems the next properties
class TestSubItems extends Model
{
use HasFactory;
/**
* The primary key associated with the table.
*
* #var string
*/
protected $primaryKey = 'itemNo';
/**
* Indicates if the model's ID is auto-incrementing.
*
* #var bool
*/
public $incrementing = false;
/**
* The data type of the auto-incrementing ID.
*
* #var string
*/
protected $keyType = 'string';
}
Related
I'm creating a clone for a website where parents can create a list of things they need for their newborn baby so other people can buy it for them as a gift.
At this moment I've managed to insert data into my table and to link that row of data to the user id (so user who is logged in and completed the form).
I've managed to show all the lists from all the user id's but when I go to the dashboard of the authenticated user, I only want to show the lists who is linked to his user_id.
I can't get it working but I'm sure I have to use hasMany() and belongsTo().
This is my code:
My migration:
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique;
$table->binary('password');
$table->enum('role', ['user','admin'])->default('user');
$table->timestamp('created_at');
$table->timestamp('updated_at');
});
Schema::create('lists', function (Blueprint $table)
{
$table->increments('id');
$table->foreignId('user_id')->nullable()->constrained()->onDelete('cascade');
$table->string('baby');
$table->string('vader');
$table->string('moeder');
$table->integer('telefoonnummer');
$table->string('email');
$table->string('adres');
$table->integer('huisnummer');
$table->string('toevoeging')->nullable();
$table->string('stad');
$table->integer('postcode');
$table->string('land');
});
}
My User model:
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array<int, string>
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for serialization.
*
* #var array<int, string>
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast.
*
* #var array<string, string>
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function birthLists()
{
return $this->hasMany(Birthlist::class, 'user_id');
}
}
My Birthlist model:
class Birthlist extends Model
{
use HasFactory;
protected $table = 'lists';
protected $primaryKey = 'id';
protected $fillable =
[
'user_id',
'baby',
'vader',
'moeder',
'telefoonnummer',
'email',
'adres',
'huisnummer',
'toevoeging',
'stad',
'postcode',
'land'
];
public $timestamps = false;
public function user()
{
return $this->belongsTo(User::class, 'user_id');
}
}
My controller
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Providers\RouteServiceProvider;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use App\Models\User;
use App\Models\Birthlist;
class DashController extends Controller
{
public function dashboard($id)
{
$userId = Auth::id();
$lists = Birthlist::where('user_id')->first();
return view('dashboard', [
'lists' => $lists,
]);
}
}
My view
<body class="bg-red-100 w-screen h-screen pb">
<main class="">
<div class="text-center p-8 bg-green-100">
<p class="">welkom</p>
<h2 class="text-3xl font-bold">{{ Auth::user()->name }}</h2>
</div>
<section class="bg-red-100">
<span class="p-4"><p class="text-center text-xl font-semibold">Mijn lijsten</p></span>
#foreach ($lists->birthLists as $list)
<div class="bg-red-200 p-8 bg-gradient-to-b from-green-300 to-fuchsia-400 drop-shadow-xl text-white md:w-5/12 xl:w-3/12">
<div class="text-3xl font-bold">
{{ $list->baby }}
</div>
<div class="flex flex-row justify-between">
{{ $list->vader }} & {{ $list->moeder }}
</div>
</div>
#endforeach
</section>
</main>
#include('partials.footer')
</body>
In User model :
public function birthLists()
{
return $this->hasMany(Birthlist::class);
}
and in view :
<body class="bg-red-100 w-screen h-screen pb">
<main class="">
<div class="text-center p-8 bg-green-100">
<p class="">welkom</p>
<h2 class="text-3xl font-bold">{{ Auth::user()->name }}</h2>
</div>
<section class="bg-red-100">
<span class="p-4"><p class="text-center text-xl font-semibold">Mijn lijsten</p></span>
#foreach (auth()->user()->birthLists as $list)
<div class="bg-red-200 p-8 bg-gradient-to-b from-green-300 to-fuchsia-400 drop-shadow-xl text-white md:w-5/12 xl:w-3/12">
<div class="text-3xl font-bold">
{{ $list->baby }}
</div>
<div class="flex flex-row justify-between">
{{ $list->vader }} & {{ $list->moeder }}
</div>
</div>
#endforeach
</section>
</main>
#include('partials.footer')
</body>
and don't need to get data from controller because you can get birthLists in blade file.
I'm facing against this problem since yesterday.
I have a db table called resources have a foreign key linked to another table called category.
I'm trying to retrieve the description field in my blade view, but I get this error:
Trying to get property 'description' of non-object.
My blade view:
#extends('templates.header')
#section('section')
<div class="p-10 grid grid-cols-1 sm:grid-cols-1 md:grid-cols-3 lg:grid-cols-3 xl:grid-cols-3 gap-5">
#foreach($resources as $resource)
<div class="max-w-sm rounded overflow-hidden shadow-lg">
{{-- <img class="w-full" src="#" alt="Mountain"> --}}
<div class="px-6 py-4">
<div class="font-bold text-xl mb-2">
{{ $resource->name }}
</div>
<p class="text-gray-700 text-base">
{{ $resource->description }}
</p>
</div>
<div class="px-6 pt-4 pb-2">
<span class="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2 mb-2">{{ $resource->categor->description }}</span>
<span class="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2 mb-2">{{ $resource->status }}</span>
<span class="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2 mb-2">{{ $resource->centerId }}</span>
<button type="submit" class="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
Prenota
</button>
</div>
</div>
#endforeach
</div>
#endsection
My Resource Model:
namespace App\Models;
use App\Models\Category;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Resource extends Model
{
use HasFactory;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name',
'description',
'category',
'inventoryN',
'status',
'centerId',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
];
public function category()
{
return $this->hasOne(Category::class, 'id', 'category');
}
}
My Category Model:
namespace App\Models;
use App\Models\Resource;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
use HasFactory;
protected $table = 'categories';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'description',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
];
public function resource()
{
return $this->belongsTo(Resource::class, 'category');
}
}
And lastly my ResourceController:
namespace App\Http\Controllers;
use App\Models\Category;
use App\Models\Resource;
use Illuminate\Http\Request;
class ResourceController extends Controller
{
public function index()
{
$resources = Resource::with('category')->get();
return view('resources', compact('resources'));
}
}
This is a dd of "$resources":
dd of $resources
You have a few mistakes here.
The first is in the Blade. You need to fix a typo
$resource->categor->description
// should be
$resource->category->description
Then I recommend changing your schema by changing your resources column from category to category_id.
This will help Laravel auto populate the values in the below snippets.
Next, you need to fix your relationships.
In the Resources model, you need
public function category()
{
return $this->hasOne(Category::class);
}
I have removed the second and third parameters, these are autofilled by Laravel; and since you are using Laravel's naming schemes, you don't need it.
What you had previously was stating that the table was the singular variant of category, which it wasn't.
Then you need to change your Category model to
public function resource()
{
return $this->belongsTo(Resource::class);
}
The reason this was failing is because Laravel was returning null, because the column names weren't quite correct.
It's easier to just have a more standard naming structure in your Database as it helps other developers, and makes your life easier when using Laravel.
There is a typo in your category viewing. I think that's the problem.
{{ $resource->categor->description }}
vs.
{{ $resource->category->description }}
im using Laravel 6.2
I want to make a inventory database system. i have 2 modals Produk and Stock.
in that case, i want to input data p_name and sku from ProdukTable and place it into StockTable using Eloquent ORM.
I tried using belongsTo(),
Here's my modal Produk code
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Produk extends Model
{
public $table = 'produk';
protected $primaryKey = 'pid';
protected $fillable = [
'pid',
'p_nama',
'sku',
'p_harga',
'status'
];
}
Here's my modal Stock code
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Stock extends Model
{
public $table = 'stock';
protected $primaryKey = 'sid';
protected $fillable = [
'sid',
'p_nama',
'sku',
'p_stock_min',
'p_stock',
'status'
];
public function produk()
{
return $this->belongsTo('App\Produk', 'pid');
}
}
My StockController
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Stock;
use App\Produk;
use RealRashid\SweetAlert\Facades\Alert;
class StockController extends Controller
{
public function index()
{
$datas = Stock::paginate(5); // 5 record per pages
return view('stock.list', compact('datas'));
// $datas = Stock::all();
// return $datas;
}
. . . .
}
My View stock.blade
<div class="body">
<div>
<i class="zmdi zmdi-account-add"></i> Tambah Stock
<a style="margin: 2px;" href="{{ route('stock.index')}}" class="btn btn-primary btn-sm"><i class="zmdi zmdi-refresh"></i></a>
</div>
<div class="col-sm-12">
#if(session()->get('success'))
<div class="alert alert-success">
{{ session()->get('success') }}
</div>
#endif
</div>
<table class="table table-bordered table-striped table-hover dataTable js-exportable">
<thead>
<tr>
<th class="text-center" style="width:5%">#</th>
<th class="text-center" style="width:25%">Nama Produk</th>
<th class="text-center" style="width:10%">SKU Produk</th>
<th class="text-center" style="width:8%">Min. Stock</th>
<th class="text-center" style="width:8%">Stock</th>
<th class="text-center" style="width:10%">Status</th>
<th class="text-center" style="width:10%">Aksi</th>
</tr>
</thead>
<tbody>
#if(!empty($datas) && $datas->count())
#foreach($datas as $data)
<tr>
<th class="text-center">{{ $loop->iteration }}</th>
<td>{{ $data->produk }}</td>
<td>{{ $data->p_nama }}</td>
<td>{{ $data->p_stock_min }}<code> pcs</code></td>
<td>{{ $data->p_stock }}<code> pcs</code></td>
<td class="text-center">{{ $data->status }}</td>
<td class="text-center">
<i class="zmdi zmdi-edit"></i></span>
<i class="zmdi zmdi-delete"></i></span>
</td>
</tr>
#endforeach
#else
<tr>
<td colspan="8">Data tidak ditemukan! Silahkan buat data Stock terlebih dahulu.</td>
</tr>
#endif
</tbody>
</table>
{!! $datas->links() !!}
</div>
Migration Stock
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateStocksTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('stock', function (Blueprint $table) {
$table->bigIncrements('sid');
$table->bigInteger('produk_id')->unsigned();
$table->string('p_nama');
$table->string('sku');
$table->integer('p_stock_min');
$table->integer('p_stock')->nullable();
$table->string('status');
$table->timestamps();
});
Schema::table('stock', function (Blueprint $table) {
$table->foreign('produk_id')->references('pid')->on('produk')
->onDelete('cascade')->onUpdate('cascade');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('stock');
}
}
Response when i add data direct from PMA
[{"sid":1,"produk_id":6,"p_nama":"kopi1","sku":"12345678","p_stock_min":20,"p_stock":800,"status":"Aktif","created_at":"2020-11-24 16:37:16","updated_at":"2020-11-24 16:37:16"},
{"sid":2,"produk_id":7,"p_nama":"kopi2","sku":"87654321","p_stock_min":20,"p_stock":600,"status":"Aktif","created_at":"2020-11-24 16:37:16","updated_at":"2020-11-24 16:37:16"}]
i dunno where's my mistake ?
just want to add data p_produk into stock table using select form, and when i select it sku data will be generate as same as data on table Produk.
In your Stock model you should put the foreign key in the belongsTo relation. Edit the method like so:
public function produk()
{
return $this->belongsTo('App\Produk', 'produk_id');
}
Using Laravel conventions the relationship produk should be defined as
public function produk()
{
return $this->belongsTo(Produk::class, 'produk_id', 'pid');
}
To dynamically change the value of sky in the readonly input on create.blade.php based on the option selected by the user in select control showing $produk->p_nama:
Give an id to the readonly input for sku
<div class="form-group">
<label for="sku">SKU:</label>
<input type="text" class="form-control form-control-lg" name="sku" id="skuSelected" readonly/>
</div>
Track the option selected in select control
<select class="form-control select2" name="p_name" onChange="setSku(this);">
#foreach($produks as $produk)
<option value="{{ $produk->pid }}">{{ $produk->p_nama }}</option>
#endforeach
</select>
Handle the change in selection via javascript
<script>
function setSku(sel) {
const sku = sel.options[sel.selectedIndex].text;
document.getElementById('skuSelected').value = sku;
}
</script>
because you are not naming your columns on the laravel naming conventions
you have to define it all by yourself if you want to use this naming like this :
public function produk()
{
return $this->belongsTo('App\Produk', 'pid' , 'id');
}
as belongsTo takes $relatedModel , $foreignKey , $ownerKey in a row
I am working on a library application and I want to create a function where the user can rent out a book to a customer. However, I want the books that are rented out right now to not show up in the select box when renting out another book.
I have looked up several articles about this, but couldn't really make up a solution so I would be happy about any help.
The idea is, that when a book has the attribute "maxreturndate" set it won't show up.
CheckedOutController:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\CheckedOut;
use App\Book;
use App\Reader;
class CheckedOutController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
$checkedOuts = CheckedOut::with(['book', 'reader'])->get();
return view('checkedouts/index', compact('checkedOuts'));
}
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function create()
{
$books = Book::all();
$readers = Reader::all();
return view('checkedouts/create', compact('books','readers'));
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$validatedData = $request->validate([
'book_id' => 'required',
'reader_id' => 'required',
'maxreturndate' => 'required|date',
'returndate' => 'nullable',
]);
$checkedOut = CheckedOut::create($validatedData);
return redirect('checkedouts')->with('success', 'Buch wurde erfolgreich verliehen!');
}
/**
* Display the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function show($id)
{
//
}
/**
* Show the form for editing the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function edit($id)
{
//
}
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param int $id
* #return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
//
}
/**
* Remove the specified resource from storage.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function destroy($id)
{
//
}
}
index.blade.php
#extends('layout')
#section('title')
<title>Alle ausgeliehen Bücher</title>
#section('content')
<style>
.uper {
margin-top: 40px;
}
</style>
<div class="uper">
#if(session()->get('success'))
<div class="alert alert-success">
{{ session()->get('success') }}
</div><br />
#endif
<table class="table table-hover">
<thead>
<tr>
<td>ID</td>
<td>Titel</td>
<td>Verliehen an</td>
<td>Verleihdatum</td>
<td>Fällig am</td>
<td>Zurückgebracht am</td>
<td colspan="2">Funktionen</td>
</tr>
</thead>
<tbody>
#foreach($checkedOuts as $checkedOut)
<tr>
<td>{{$checkedOut->id}}</td>
<td>{{$checkedOut->book->title}}</td>
<td>{{$checkedOut->reader->name}}</td>
<td>{{$checkedOut->created_at}}</td>
<td >{{$checkedOut->maxreturndate}}</td>
<td>{{$checkedOut->returndate}}</td>
<td></td>
<td>Bearbeiten</td>
<td>Anzeigen</td>
<td>
<form action="{{ route('checkedouts.destroy', $checkedOut->id)}}" method="post">
#csrf
#method('DELETE')
<button class="btn btn-danger" type="submit">Löschen</button>
</form>
</td>
</tr>
#endforeach
</tbody>
</table>
<div>
#endsection
Migrations:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateCheckedOutsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('checked_outs', function (Blueprint $table) {
$table->bigIncrements('id');
$table->bigInteger('book_id')->unsigned();
$table->foreign('book_id')->references('id')->on('books')->onDelete('cascade');
$table->bigInteger('reader_id')->unsigned();
$table->foreign('reader_id')->references('id')->on('readers')->onDelete('cascade');
$table->date('maxreturndate');
$table->date('returndate')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('checked_outs');
}
}
create.blade.php
#extends('layout')
#section('title')
<title>Buch verleihen</title>
#section('stylesheets')
<script src="http://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/select2#4.0.13/dist/js/select2.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/select2#4.0.13/dist/css/select2.min.css" rel="stylesheet" />
#endsection
#section('content')
<style>
.uper {
margin-top: 40px;
}
</style>
<div class="card uper">
<div class="card-header">
Buch verleihen
</div>
<div class="card-body">
<form method="post" action="{{ route('checkedouts.store') }}">
<div class="form-group">
#csrf
<label for="book_id">Buch:</label>
<select name="book_id" class="form-control select2-single <!-- #error('book_id') is-invalid #enderror -->">
#foreach ($books as $book)
<option value="{{ $book->id }}">{{ $book->title }}</option>
#endforeach
</select>
#error('book_id')
<div class="alert alert-danger">{{ $message }}</div>
#enderror
</div>
<div class="form-group">
<label for="reader_id">Verleihen an:</label>
<select name="reader_id" class="form-control select2-single <!-- #error('reader_id') is-invalid #enderror -->">
#foreach ($readers as $reader)
<option value="{{ $reader->id }}">{{ $reader->name }}</option>
#endforeach
</select>
#error('reader_id')
<div class="alert alert-danger">{{ $message }}</div>
#enderror
</div>
<div class="form-group">
<label for="maxreturndate">Zurückbringen bis:</label>
<input type="date" class="form-control" name="maxreturndate" />
#error('name')
<div class="alert alert-danger">{{ $message }}</div>
#enderror
</div>
<button type="submit" class="btn btn-primary">Verleihen</button>
</form>
</div>
</div>
<script type="text/javascript">
$(".select2-single").select2();
</script>
#endsection
The relationship between the 3 Models:
Book:
public function checkedOut(){
return $this->hasOne(CheckedOut::class);
}
Reader:
public function checkedOut()
{
return $this->belongsTo(CheckedOut::class);
}
CheckedOut:
public function book(){
return $this->belongsTo(Book::class);
}
public function reader(){
return $this->belongsTo(Reader::class);
}
My suggestion is to set up Books and Readers with a many-to-many relationship. Now, your models could look like this:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\Pivot;
class Book extends Model
{
public function readers()
{
return $this
->belongsToMany(\App\Reader::class, 'checked_outs')
->using(\App\Checkout::class)
->withPivot(['returndate', 'maxreturndate']);
}
}
class Reader extends Model
{
public function books()
{
return $this
->belongsToMany(\App\Book::class, 'checked_outs')
->using(\App\Checkout::class)
->withPivot(['returndate', 'maxreturndate']);
}
}
class Checkout extends Pivot
{
// this should be named `book_reader` but we override it here
$table = "checked_outs";
$dates = [
"maxreturndate",
"returndate",
];
}
I have created a pivot model which isn't necessary, but allows you to operate directly on the pivot table and cast the extra attributes to dates automatically. Whether this is useful is a matter of opinion. You should rename the checked_outs table to book_reader which is the naming convention that Laravel expects for a pivot table.
Getting the books that aren't checked out is simple enough to do as follows, using the doesntHave method to check for absence of a relationship.
public function create()
{
$books = Book::doesntHave("readers")->get();
$readers = Reader::all();
return view('checkedouts/create', compact('books','readers'));
}
And "checking out" a book could look like this:
public function store(Request $request)
{
$reader = Reader::find($request->reader_id);
$reader
->books()
->attach(
$request->book_id,
["returndate" => Carbon\Carbon::now()->addDays(7)]
);
}
when a book has the attribute "maxreturndate" set it won't show up
Since you did not specify in your migration, I am going to assume here that you have a maxreturndate nullable field in your books table, then you should be able to simply create a local scope when you want your list of "not rented" books.
Here's an example on creating a notRented scope:
// in your Book model define the local scope
public function scopeNotRented($query){
return $query->whereNotNull('maxreturndate');
}
// in the create method of your controller
public function create()
{
$books = Book::notRented()->get();
$readers = Reader::all();
return view('checkedouts/create', compact('books','readers'));
}
I have a form in which you submit a "project". One of the field is "created by", but the user does not update this, it gets the name of the authenticated user in that moment and inserts it into the db.
I know how to retrieve the user's name, but the problem is that when I login with another user, then all the name change, because I store the name each time.
This is my project controller
<?php
namespace App\Http\Controllers;
use App\Project;
use App\Client;
use Auth;
use Illuminate\Http\Request;
class ProjectController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function __construct()
{
$this->middleware('auth');
}
public function index()
{
return view('projects.index', [
'project' => Project::all()
]);
}
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function create()
{
if (Auth::user()->role != 1){
return redirect()->back();
}else{
return view('projects.create',[
'project' => new Project,
'client' => new Client
]);
}
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(Request $r)
{
$validatedData = $r->validate([
'proj_title' => 'required|max:100',
'client_id' => 'required',
'proj_desc' => 'required',
]);
$currentUser = Auth::user()->name;
$r['created_by'] = $currentUser;
$project = Project::create($r->all());
return redirect('/projects')->with('store','');
}
/**
* Display the specified resource.
*
* #param \App\Project $project
* #return \Illuminate\Http\Response
*/
public function show(Project $project)
{
//
}
/**
* Show the form for editing the specified resource.
*
* #param \App\Project $project
* #return \Illuminate\Http\Response
*/
public function edit(Project $project)
{
return view('projects.edit', compact('project'));
}
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param \App\Project $project
* #return \Illuminate\Http\Response
*/
public function update(Request $r, Project $project)
{
$project->update($r->all());
return redirect('/projects')->with('update','');
}
/**
* Remove the specified resource from storage.
*
* #param \App\Project $project
* #return \Illuminate\Http\Response
*/
public function destroy(Project $project)
{
$project->delete();
return redirect('/projects')->with('delete','');
}
}
And this is my index
#section('content')
<div class="row">
<div class="col">
#if (Auth::user()->role == 1)
<a class="btn btn-success" href="/projects/create">Add Project</a>
#endif
</div>
<div class="col"></div>
<div class="col">
#if(session()->has('store'))
<div class="alert alert-success mt-2" role="alert">
<strong>Project created</strong>
</div>
#elseif(session()->has('update'))
<div class="alert alert-success mt-2" role="alert">
<strong>Project updated</strong>
</div>
#elseif(session()->has('delete'))
<div class="alert alert-success mt-2" role="alert">
<strong>Project deleted</strong>
</div>
#endif
</div>
</div>
<br>
<table class="table table-bordered table-hover">
<thead>
<tr>
<th>Project Id</th>
<th>Title</th>
<th>Description</th>
<th>Client Id</th>
<th>Created by</th>
<th>Created on</th>
#if (Auth::user()->role==1)
<th>Admin</th>
#endif
</tr>
</thead>
<tbody class="">
#foreach ($project as $project)
<tr>
<td>{{$project->proj_id}}</td>
<td>{{$project->proj_title}}</td>
<td>{{$project->proj_desc}}</td>
<td>{{$project->client_id}}</td>
<td>{{$project->Auth::user()->name}}</td>
<td>{{$project->created_at}}</td>
#if (Auth::user()->role==1)
<td>
<div class="dropdown">
<button class="btn btn-danger dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Action</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<a class="dropdown-item" href="{{route('projects.edit',$project)}}">Edit</a>
<form method="POST" action="{{route('projects.destroy',$project)}}" onsubmit="return confirm('Are you sure you want to delete this?')">
#method('DELETE')
#csrf
<button class="dropdown-item" type="submit">Delete</button>
</form>
</div>
</div>
</td>
#endif
</tr>
#endforeach
</tbody>
</table>
#endsection
I think your problem is that you are using:
{{ $project->Auth::user()->name }}
instead of
{{ $project->created_by }}