I am beginner of laravel, I want to store a book to books database, but after click button, it shows "Method Illuminate\Database\Eloquent\Collection::books does not exist." What am I missing? here are my codes.
BookController
public function create()
{
return view('books.create');
}
public function store(Request $request)
{
$this->validate($request, [
'book' => 'required|max:255',
'category' => 'required',
'quantity' => 'required|numeric',
'price'=>'required|numeric',
'info'=>'required'
]);
//$request->user()->member()->books()->create([
$member=auth()->user()->member()->get();
$member->books()->create([
'book' => $request->book,
'category' => $request->category,
'quantity' => $request->quantity,
'price'=>$request->price,
'info'=>$request->info
]);
return redirect('shops')->with('success', 'successful');
}
books.create
<form action="{{route('books.store')}}" method="POST" role="form">
@csrf
@method('POST')
<div class="form-group">
<label for="book">name:</label>
<input id="book" name="book" class="form-control" placeholder="enter book name">
</div>
<div class="form-group">
<label for="category">category:</label>
<input id="category" name="category" class="form-control" placeholder="enter category">
</div>
<div class="form-group">
<label for="quantity">quantity:</label>
<input id="quantity" name="quantity" class="form-control" placeholder="enter quantity">
</div>
<div class="form-group">
<label for="price">price:</label>
<input id="price" name="price" class="form-control" placeholder="enter price">
</div>
<div class="form-group">
<label for="info">info:</label>
<textarea id="info" name="info" class="form-control" rows="10" placeholder="enter info"></textarea>
</div>
<button type="submit" class="btn-sm btn-primary">create</button>
</form>
User and Member is one to one relation, and Book belongs to one Member
Book Model
public function member()
{
return $this->belongsTo(Member::class);
}
protected $fillable = ['book','category','quantity','price','info'];
Member Model
public function books()
{
return $this->hasMany(Book::class);
}
public function user()
{
return $this->belongsTo(User::class);
}
User Model
public function member()
{
return $this->hasOne(Member::class);
}
books,user and member migration
books migration
public function up()
{
Schema::create('books', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('member_id');
$table->foreign('member_id')->references('id')->on('members')->onDelete('cascade');
$table->string('name');
$table->integer('quantity');
$table->integer('price');
$table->string('path');
$table->string('info');
$table->string('category');
$table->timestamps();
});
}
member migration
public function up()
{
Schema::create('members', function (Blueprint $table) {
$table->increments('id');
$table->unsignedbigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->string('sex');
$table->string('email');
$table->string('address');
$table->string('tel');
$table->timestamps();
});
}
user migration
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->foreignId('current_team_id')->nullable();
$table->text('profile_photo_path')->nullable();
$table->timestamps();
});
}
You are receiving a Collection from this chain of calls:
$member = auth()->user()->member()->get();
get
is going to always return a Collection when called on a relationship method. If you want a single model you can call first
instead:
$member = auth()->user()->member()->first();
Though first
could return null
so you may need to check that.
Another method to access the result of this relationship would be to use the dynamic property for the relationship member
:
$member = auth()->user()->member;
Since that relationship is defined as a HasOne
it knows to load it for a single result or null
.
Assuming $member
isn't null
at this point you should be fine with the rest how it is.
$member=auth()->user()->member()->get();
returns a collection not an object of Member class. Use $member=auth()->user()->member()->first();
or $member=auth()->user()->member;
Try this
public function store(Request $request)
{
$this->validate($request, [
'book' => 'required|max:255',
'category' => 'required',
'quantity' => 'required|numeric',
'price'=>'required|numeric',
'info'=>'required'
]);
$member=auth()->user()->member;
if($member){
$member->books()->create([
'book' => $request->book,
'category' => $request->category,
'quantity' => $request->quantity,
'price'=>$request->price,
'info'=>$request->info
]);
return redirect('shops')->with('success', 'successful');
}
//Member is not found, return with error
return redirect()->back()->with('error', 'Member not found');
}
That error is due to the fact that this call $member=auth()->user()->member()->get();
. It's supposed to return a Collection
of Member
.
So when you try to call books
on a collection hold by the variable member
It' won't succeed as Illuminate\Support\Collection
Class doesn't define a method books
you have to loop trought that collection by using a foreach
loop or a each
or map
method from Collection
.
$member->each(function($member){
$member->books()->create([
//
]);
});
Or has you have already define in User
Model that user
will always have a single Member by using hasOne
method.
So you can use auth()->user()->member()->first();
which return a single instance of type Member
on which you call books
method but with that you have to be sure that the Authenticated use has already one member which is attached to him to avoid any error. even though that is the case you can always check if variable $member
is not null with an if
statement
$member = auth()->user()->member()->first();
if($member){
// here you can have access to `books`
$member->books()->create([
//...
]);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.