Many to Many relation in Laravel5.4 - php

I Want to Create multi category for posts in database but I Just create one category with this code:
post.php
public function Category()
{
return $this->belongsTo('App\Category');
}
Category.php
public function posts()
{
return $this->belongsToMany('App\Post');
}
posts_table:
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id');
$table->integer('category_id');
$table->string('title');
$table->integer('price');
$table->string('description');
$table->timestamps();
});
}
and view for create category is here:
<form method="post" action="/storePost">
{{csrf_field()}}
<input type="hidden" id="user_id" name="user_id" value="
{{Auth::user()->id}}">
<lable>title</lable>
<input type="text" id="title" name="title">
<label>description</label>
<input type="text" id="description" name="description">
<label>price</label>
<input type="text" name="price" id="price">
<label>Category</label>
<select name="category_id">
#foreach($categories as $category)
<option value={{$category->id}}>{{$category->name}}</option>
#endforeach
</select>
<button type="submit" id="AddProduct">add</button>
</form>
And my postcontroller to create category is:
public function store()
{
Post::create([
'user_id'=>request('user_id'),
'title' => request('title'),
'category_id'=>request('category_id'),
'description'=>request('description'),
'price'=>request('price'),
]);
return redirect('/show');
}
How I Can create multi category for one posts in table?

You are going to need to design your database somewhat differently. You need a proper join table between the two tables. Your database should look something like this:
posts
id
//other
categories
id
//other
post_categories
post_id
category_id
Once you have the database setup with a proper join. You have to define the relations a little bit differently:
// App\Models\Post
public function categories() {
return $this->belongsToMany('App\Category', 'post_categories', 'category_id', 'post_id');
}
// App\Models\Category
public function posts() {
return $this->belongsToMany('App\Post', 'post_categories', 'post_id', 'category_id');
}
You can then use attach and detach to add and remove relations:
$post = Post::find(1);
$post->categories()->attach($categoryId);
You can read more about many-to-many relationships in the Laravel Documentation.

Related

Laravel : How to Create Dropdown to Select FOREIGN KEY from Other Table?

i want to ask you how to select FOREIGN KEY (from "doa_id in "doas" table) when user create a new data (to the "notes table) in a form. This is my code :
NoteController.php
public function create()
{
return view('note/create');
}
public function store(Request $request)
{
$userId = Auth::user()->id;
Note::create([
'title' => $request->title,
'detail' => $request->detail,
'user_id' => $userId,
'mood_id' => $request->mood_id,
'doa_id' => $request->doa_id,
]);
return redirect('notes');
}
2021_05_28_020438_create_notes_table.php migration
class CreateNotesTable extends Migration
{
public function up()
{
Schema::create('notes', function (Blueprint $table) {
$table->id('note_id');
$table->string('title');
$table->date('created_at');
$table->date('updated_at');
$table->text('detail');
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');
//mood FK
$table->unsignedBigInteger('mood_id');
$table->foreign('mood_id')->references('mood_id')->on('moods');
//doa FK
$table->unsignedBigInteger('doa_id');
$table->foreign('doa_id')->references('doa_id')->on('doas');
});
}
public function down()
{
Schema::dropIfExists('notes');
}
}
and this is my dropdown html :
<div class="container">
<label class="form-label text-white" style="font-weight: bold;" for="doa">Doa terkait</label>
<select class="form-select" style="color: #41A7A5" aria-label="Default select example">
<option selected>Pilih doa</option>
</select>
</div>
In Dropdown option, I want to show "doa_name" based on it's "doa_id"
Thank you :)
You can put the logic in the NoteController and the view. For example, to get a collection of all options for the foreign key, pass the collection to the view.
public function create()
{
$doas = Doas::all();
return view('note/create', compact('doas'));
}
Then on the view, you can perform a foreach loop using the select HTML tag.
<div class="container">
<label class="form-label text-white" style="font-weight: bold;" for="doa">Doa terkait</label>
<select class="form-select" style="color: #41A7A5" aria-label="Default select example">
#foreach ($doas as $doa)
<option value="{{$doa-id>}}">{{$doa->name}}</option>
#endforeach
</select>
</div>
After this, it's just using the input in your store() method.

Method Illuminate\Database\Eloquent\Collection::books does not exist.(laravel)

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([
//...
]);
}

Troubling to show sub-categories in the Categories Dropdown list

in my code,i want to show category and sub catagory under the Category in the Products table.
Here is my categories table
1.
public function up() { Schema::create('categories', function (Blueprint $table) {
$table->increments('id');
$table->integer('parent_id'); //sub category id
$table->string('name');
$table->rememberToken();
$table->timestamps();
});
}
Here is my products table
2.
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->increments('id');
$table->integer('category_id');
$table->string('product_name');
$table->timestamps();
});
}
Here is my Category Model
3.Category.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Category extends Model { protected $guarded=[];
public function products(){
return $this->hasMany('App\Product');
}
public function parent(){
return $this->belongsTo('App\Category','parent_id','id');
}
}
Here is my Product Model
4.Product.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
public function category(){
return $this->hasone('class::Category');
}
}
Now here is my ProductsController.php
5.ProductsController.php
<?php
namespace App\Http\Controllers;
use App\Category;
use App\Product;
use Session;
use Illuminate\Http\Request;
class ProductsController extends Controller
{
public function product(){
return view('admin.products.product');
}
}
Here is my product.blade.php file
<form class="form-horizontal" method="post" action="{{route('add.product')}}" name="add_product" id="add_product" novalidate="novalidate">
#csrf
<div class="control-group">
<label class="control-label">main Category </label>
<div class="controls">
<select name="category_id" id="category_id" style="width:220px;">
#foreach(App\Category::all() as $cat)
<option value="{{$cat->id}}" >{{ $cat->parent()->name ? $cat->parent()->name . ' -- ' : '' }}{{$cat->name}}</option>
#endforeach
</select>
</div>
</div>
<div class="control-group">
<label class="control-label">Product Name</label>
<div class="controls">
<input type="text" name="product_name" id="product_name">
</div>
</div>
<div class="form-actions">
<input type="submit" value="submit" class="btn btn-success">
</div>
</form>
I want to data like this in my product.blade.php
what data i want
thats why i use this code in product.blade.php
#foreach(App\Category::all() as $cat)
<option value="{{$cat->id}}" >{{ $cat->parent()->name ? $cat->parent()->name . ' -- ' : '' }}{{$cat->name}}</option>
#endforeach
but i facing error like this
ErrorException (E_ERROR)
Undefined property: Illuminate\Database\Eloquent\Relations\BelongsTo::$name (View: F:\laragon\www\flipcart\resources\views\admin\products\product.blade.php)
Previous exceptions
Undefined property: Illuminate\Database\Eloquent\Relations\BelongsTo::$name (0)
There are a number of things you may want to review in this code as there are several odd bits.
The error you are getting is caused by this code:
$cat->parent()->name
You are accessing a query builder instance when you call a relationship as a method rather than a property (i.e. ->parent() rather than ->parent).
Try this instead:
$cat->parent->name
Your ternary statement should then be replaced with something like this:
$cat->parent ? $cat->parent->name . ' -- ' : ''

How to insert multiple role in employee table using laravel

I'm building API and I'm struggling with store data for multiple employee roles, how to store, could you provide me some example,
sorry for using the foreign language.
Karyawan=employee,
Jabatan=role
Karyawan.php
public function jabatan() {
return $this->hasMany('\App\Jabatan','id_jabatan');
}
Jabatan.php
public function karyawan(){
return $this->belongsTo('\App\Karyawan','id_jabatan');
}
how to KaryawanController at store function should be...
this is my model and controller
i created my pivot table and i got this error
SQLSTATE[42S22]: Column not found: 1054 Unknown column '0' in 'field list' (SQL: insert into tb_jabatan_karyawan (id_jabatan, id_karyawan, 0, 1) values (0, 57, 1, 2))
ini controller sama modelnya..
I am using User and Role instead of Karyawan and Jabatan respectively (sorry for that). User and Role has Many-to-Many relation because one User may have multiple Roles and vice versa.
roles Table
+----+------+-----------+
| id | role | timeStamps|
+----+------+-----------+
role_user Pivot Table
+----+---------+---------+
| id | user_id | role_id |
+----+---------+---------+
Role Model
public function users(){
return $this->belongsToMany('App\User');
}
User Model
public function roles(){
return $this->belongsToMany('App\Role');
}
RoleUser Pivot
namespace App;
use Illuminate\Database\Eloquent\Relations\Pivot;
class RoleUser extends Pivot
{
protected $table='role_user';
protected $fillable = [
'user_id','role_id'
];
public static $role_attach_rules = [
'roles' => 'required|array|min:1|exists:roles,id'
];
public function user(){
return $this->hasOne('App\User', 'id', 'user_id');
}
public function role(){
return $this->hasOne('App\Role', 'id', 'user_id');
}
}
Controller Code for Assigning Roles to the User
Here you will understand the methods by their names.
public function getAssignRole(){
$users = User::all();
$roles=Role::all();
return View::make('assignrole', compact('users', 'roles'));
}
public function postAssignRole(Request $request){
$attachvalidator = Validator::make($request->all(),RoleUser::$role_attach_rules);
if ($attachvalidator->fails()){
return Redirect::back()->withErrors($attachvalidator)->withInput();
}
$user=$request->get('user');
$role=$request->get('roles');
$attach = User::find($user)->roles()->attach($role);
return 'Success';
}
public function detachRole(Request $request){
$user=$request->get('user_update');
$role=$request->get('roles_update');
$attach = User::find($user)->roles()->detach($role);
return 'detach Success';
}
View file (assignrole.blade.php) for Assigning Roles
//This form is for assigning roles
<form method="post" action="{{route('role.assignrole.post')}}">
{{csrf_field()}}
<select id="user" name="user" class="select_with_style" required>
#foreach($users as $user)
<option value="{{$user['id']}}">{{$user['name']}}</option>
#endforeach
</select>
<select id="roles" name="roles[]" class="select_with_style" multiple="" required>
#foreach($roles as $role)
<option value="{{$role['id']}}">{{$role['role']}}</option>
#endforeach
</select>
<br>
<input type="submit" name="submit" class="submit action-button" value="Submit"/>
</form>
//This is for detaching roles from user
<form method="post" action="{{route('role.detach')}}">
{{csrf_field()}}
<select id="user_update" name="user_update" class="select_with_style" required>
#foreach($users as $user)
<option value="{{$user['id']}}">{{$user['name']}}</option>
#endforeach
</select>
<select id="roles_update" name="roles_update[]" class="select_with_style" multiple="" required>
#foreach($roles as $role)
<option value="{{$role['id']}}">{{$role['role']}}</option>
#endforeach
</select>
<br>
<input type="submit" name="submit" class="submit action-button" value="Update"/>
</form>
Routes
Route::get('role/assignrole', array('as' => 'role.assignrole', 'uses' => 'YourController#getAssignRole'));
Route::post('role/assignrole', array('as' => 'role.assignrole.post', 'uses' => 'YourController#postAssignrole'));
Route::post('role/detach', array('as' => 'role.detach', 'uses' => 'YourController#detachRole'));
Hope this helps.
Edit
You can use Voyager instead of doing this much work. It is very easy to understand and well structured and I think you will love it.

Laravel relationships table show

i am new to laravel and working on relationships
i have a phonebook which it has a client in it so when i insert the data i add some client id to it how can i get the client name in phonebook view when i am showing the list of phonebooks i want to get client object and show the name with it like this $client->title
and here is my code maybe i cant define it in words :)
this is my PhonebookController
public function index()
{
$phonebooks = Phonebook::all();
$client = Phonebook::find(?dont know if its right place for it?)->client;
return view('admin.phonebooks.index',compact('phonebooks',$phonebooks),compact('client',$client));
}
and here is Phonebook model
class Phonebook extends Model{
protected $fillable = ['title','description','client_id','calldate','rememberdate'];
public function client() {
return $this->hasOne('App\Client','id');
} }
here is my phonebook db migration
Schema::create('phonebooks', function (Blueprint $table) {
$table->increments('id');
$table->text('title');
$table->longText('description');
$table->integer('client_id');
$table->dateTime('calldate');
$table->dateTime('rememberdate');
$table->timestamps();
});
and the client db migration
Schema::create('clients', function (Blueprint $table) {
$table->increments('id');
$table->text('title');
$table->longText('description');
$table->integer('fax');
$table->text('adrress1');
$table->integer('telephone1');
$table->timestamps();
});
and finally here is the view
#foreach($phonebooks as $phonebook)
<tr>
<th scope="row">{{$phonebook->id}}</th>
<th scope="row">{{$phonebook->title}}</th>
<td>{{$phonebook->description}}</td>
<td>{{$phonebook->calldate}}</td>
<td>{{$phonebook->created_at->toFormattedDateString()}}</td>
<td>{{$client->title}}</td>
<td>
<div class="btn-group" role="group" aria-label="Basic example">
<a href="{{ URL::to('admin/phonebooks/' . $phonebook->id . '/edit') }}">
<button type="button" class="btn btn-warning">edit</button>
</a>
<form action="{{url('admin/phonebooks', [$phonebook->id])}}" method="POST">
<input type="hidden" name="_method" value="DELETE">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<input type="submit" class="btn btn-danger" value="delete"/>
</form>
</div>
</td>
</tr>
#endforeach
If client hasMany Phonebook entry (and phonebook belongsTo client) then you need a client_id column on the phonebooks table
Then in the client model
public function phonebooks()
{
return $this->hasMany(App\Phonebook::class);
}
In the phonebook model
public function client()
{
return $this->belongsTo(App\Client::class);
}
In the controller
$phonebooks = Phonebook::with('client')->get();
return view('admin.phonebooks.index',compact('phonebooks'));
}
Your $phonebook models will all have a ->client relation, so in the view
<td>{{$phonebook->client->title}}</td>

Categories