i am working on laravel phonebook application i want every phonebook to hasOne clients but the clients belongs to many phone books i have a column in my phonebook table called client_id now when i set relations how can i use them in controller and pass it into view as on object and here is some of my code
phonebook controller
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));}
phonebook model
class Phonebook extends Model{protected $fillable = ['title','description','client_id','calldate','rememberdate'];public function client() {
return $this->hasOne('App\Client','id');} }
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 the view that i want to show in it
#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
you have client property in Phonebook, use it
<td>{{$phonebook->client->title}}</td>
I would suggest loading all the clients with eager loading so it will be more efficient, you can read why on the docs
You could do this on your controller:
public function index()
{
$phonebooks = Phonebook::with('client')->get();
return view('admin.phonebooks.index',compact('phonebooks',$phonebooks);
}
Then in your view you can access the phonebook client thanks to the relationship you have defined doing this:
#foreach ($phonebooks as $phonebook)
{{ $phonebook->client->title }}
#endforeach
Related
I'm actually new to Laravel and I'm trying to build a basic social network with this Framework. For this project, I created a page called post which users can add new posts. So I tried creating the posts table like this:
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id');
$table->text('caption');
$table->string('image');
$table->timestamps();
$table->index('user_id');
});
}
And on User.php model:
public function posts()
{
return $this->hasMany(Post::class);
}
And the Post.php which extends the model:
class Post extends Model
{
protected $guarded = [];
Public function user()
{
return $this->belongsTo(User::class);
}
}
And the controller which is named PostsController.php goes like this:
class PostsController extends Controller
{
public function create()
{
return view('posts.create');
}
public function store()
{
$data = request()->validate([
'caption' => 'required',
'image' => ['required','image'],
]);
auth()->user()->posts()->create($data);
dd(request()->all());
}
}
And here is the create.blade.php under the posts folder at resources dir:
#extends('layouts.app')
#section('content')
<div class="container">
<form action="/p" enctype="multipart/form-data" method="post">
#csrf
<div class="row">
<div class="col-8 offset-2">
<div class="row">
<h1>Add New Post</h1>
</div>
<div class="form-group row">
<label for="caption" class="col-md-4 col-form-label">Post Caption</label>
<input id="caption"
type="text"
class="form-control #error('caption') is-invalid #enderror"
name="caption"
value="{{ old('caption') }}"
autocomplete="caption" autofocus>
#error('caption')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
#enderror
</div>
<div class="row">
<label for="image" class="col-md-4 col-form-label">Post Image</label>
<input type="file" class="form-control-file" id="image" name="image">
#error('image')
<strong>{{ $message }}</strong>
#enderror
</div>
<div class="row pt-4">
<button class="btn btn-primary">Add New Post</button>
</div>
</div>
</div>
</form>
</div>
#endsection
And if you want to take a look at routes.php here it is:
Auth::routes();
Route::get('/p/create','PostsController#create');
Route::post('/p','PostsController#store');
Route::get('/profile/{user}', 'ProfilesController#index')->name('profile.show');
So everything looks nice and clean but the problem is whenever I try to upload some dummy pictures with a caption, I see this error:
SQLSTATE[HY000]: General error: 1 table posts has no column named caption
However I tried to run php artisan migrate syntax on CMD to check if the database migration missed anything or not, and it outputs: Nothing to migrate!
So if you know why this problem occurs or how can I fix this, please let me know, I would really appreciate that!
Thanks in advance.
In your migration you need to create the relationship, like this :
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->text('caption');
$table->string('image');
$table->timestamps();
// $table->index('user_id');
});
}
Error : You make a column for foreign key, $table->unsignedBigInteger('user_id');
But you didn't define it as a foreign key with a relationship, you need to add this line for make a relation with users table as, $table->foreign('user_id')->references('id')->on('userses')->onDelete('cascade');
Laravel 7 added Foreign Key Constraints method, in this method you can define a foreign key with one line code, as :
$table->foreignId('user_id')->constrained();
This is same as :
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
The foreignId method is an alias for unsignedBigInteger while the constrained method will use convention to determine the table and column name being referenced. If your table name does not match the convention, you may specify the table name by passing it as an argument to the constrained method:
Note : MySQL makes foreign key as an index automatically, so you don't need to define , so I delete this line $table->index('user_id'); You can find more about here.
Now, if you run php artisan migrate you will get the same Nothing to migrate! , because you already migrated all tables according to your migrations, and laravel saved all your migrated files name on a table called migrations. You need to run php artisan migrate:refresh, this command will delete your all previous table and make new table.
class Post extends Model
{
protected $guarded = [];
Public function user()
{
return $this->belongsTo(User::class,'user_id', 'id');
}
}
You can try to specify the corresponding foreign key, maybe your foreign key does not specify a pair, or you can provide your User's Model to have a look
i had the same probleme and i fixed it with this commande even if it will delete ur data in ur database but it will work
php artisan migrate:refresh
I have faced this error before and all I did was run this command:
php artisan migrate:refresh
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 . ' -- ' : ''
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>
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.
I want to use this if else statement like this:
#foreach ($comments as $comment)
<tr>
<td>
#if (is_null($ourcar))
<form method="POST" action="/comments/{{ $comment->id }}/ourcars">
{{ csrf_field() }}
<button type="submit" class="btn btn-xs btn-primary">Our cars</button>
</form>
#else
<p>saved</p>
#endif
</td>
</tr>
#endforeach
This is my controller:
public function browse(Request $request, CommentFilters $filters)
{
$lot_id = Comment::where('lot_id')->get();
$ourcar = OurCar::where('lot_id', '=', $lot_id)->first();
$comments = Comment::filter($filters)->orderBy('lot_date', 'desc')->paginate(30)->appends($request->all());
return view('comments.browse', compact(
'comments',
'ourcar'
));
}
My database structure is:
comments table: id, lot_id,
ourcars table: id, lot_id
My models:
Comment:
public function OurCar()
{
return $this->hasMany(OurCar::class);
}
OurCars:
public function Comment()
{
return $this->belongsTo(Comment::class);
}
OurCars migration:
Schema::create('ourcars', function (Blueprint $table) {
$table->engine = 'MyISAM';
$table->increments('id');
$table->integer('lot_id')->unsigned();
and it same for comments
What im trying to do is check if the lot_id already exist in "ourcars" table. If exist than return that message that this car is already saved. If not, than echo form.
With my code i have this error:
SQLSTATE[HY000]: General error: 2031 (SQL: select * from ourcars
where lot_id = ? limit 1)
Can some one recommend me a better solution?
The reason you are getting this message is because the get method will return an array , in this case it will bring all the lines of table commentplus it need 1 more argument at least to function.
$lot_id = Comment::where('lot_id')->get(); //
Also change your models to this
public function OurCar()
{
return $this->hasMany('App\Comment');
}
And this
public function Comment()
{
return $this->belongsTo('App\OurCar');
}
Here an example on how can you do it based on your code.
Pass the lot_id on the request
public function browse(Request $request, CommentFilters $filters)
{
$ourcar = OurCar::where('lot_id',$request->lot_id)->first();
$comments = Comment::filter($filters)->orderBy('lot_date', 'desc')->paginate(30)->appends($request->all());
return view('comments.browse')->with('ourcar',$ourcar)->with('comments',$comments);
}
Here the view
#foreach ($comments as $comment)
<tr>
<td>
#if ($ourcar->lot_id != $comment->lot_id)
<form method="POST" action="/comments/{{ $comment->id }}/ourcars">
{{ csrf_field() }}
<button type="submit" class="btn btn-xs btn-primary">Our cars</button>
</form>
#else
<p>saved</p>
#endif
</td>
</tr>
#endforeach