Hello i have a table called order_product that i want to get values from it and the model for that table called order_product with values:
public $timestamps = false;
protected $fillable = [
'order_id',
'product_id',
'amount',
];
This is the code of the model Order :
public $timestamps = true;
protected $fillable = [
'order_number',
'client_id',
'description',
];
public function client()
{
return $this->belongsTo(Client::class);
}
public function products()
{
return $this->belongsToMany(Product::class);
}
public function orders()
{
return $this->belongsToMany(order_product::class);
}
A professional guy helped me and explained to me how the relation worked so the client and products work very good but the orders makes error in the sql.
This is the code im executing in the controller:
$orders = Order::where('id', $id)->firstOrFail();
$orders->load('client', 'products','orders');
The error that i get is:
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'user_project_db.order_products' doesn't exist
What should be the name of the file order_product so the query can execute properly?
I change my answer after reading your answers below.
Your table relationship is orders - order_product - products.
https://webdevetc.com/blog/laravel-naming-conventions/
under Pivot tables
The way you named your pivot table is already correct.
order_product is to connect orders to products in a many-to-many.
So i think you can try to do the following.
Inside model Product add this relationship.
public function orders()
{
return $this->belongsToMany(Order::class, 'order_product');
}
And in model Order add the other connection
public function products()
{
return $this->belongsToMany(Product::class, 'order_product');
}
belongsToMany accepts 2 parameter, 1st is model destination, and 2nd is table pivot name, in your case order_product.
With this , an extra model OrderProduct is optional.
To add a product into order , you can use attach
$order = Order::find($order_id);
$order->products()->attach($product_id);
Or if you have extra fields within pivot table
// first implement this change inside Order model
return $this->belongsToMany(Product::class, 'order_product')
->withPivot('price', 'qty');
// to attach for example price and qty
$order->products()->attach($product_id, ['price' => 200', 'qty'=> 1]);
To query the price
$order_product = $order->products()
->where('product_id', $product_id)
->first()->pivot;
$price = $order_product->price;
$qty = $order_product->qty;
And back to your own query.
No need to add orders() inside Order model.
And load only the first 2 relationship should be enough.
$order->load('clients', 'products');
protected $table = 'order_products; in the model will tell Laravel that the Order model's data is stored in a table by that name.
However, typically you'd have an Order model, a Products model, and a pivot table (potentially with a pivot model, if you need it) titled order_products. https://laravel.com/docs/9.x/eloquent-relationships#defining-custom-intermediate-table-models
Related
I am trying to get product name from pivot table but unfortunately i have no idea how can i get product name from pivot table please help me thanks.
Product Model
public function category()
{
return $this->belongsToMany('App\ProductCategory', 'product_category', 'product_id', 'mf_product_category_id');
}
productcategory model
public function products()
{
return $this->belongsToMany('App\Product', 'product_category', 'mf_product_category_id', 'product_id');
}
controller
public function getproduct(Request $request)
{
// getting category Id
$categoryId = $request->category;
// getting product Id
$name = trim($request->product);
$productId = Product::where('name', $name)->pluck('id');
$getProductcategory = ProductCategoryCount::whereIn('mf_product_category_id', $categoryId)->whereIn('product_id', $productId)->get();
return $getProductcategory;
// return response()->json($getproduct);
}
As stated in laravel doc, you can retrieve pivot table extra data using withPivot on the relationship.
Define category in the Product Model
public function category()
{
return $this->belongsToMany('App\ProductCategory', 'product_category', 'product_id', 'mf_product_category_id')
->withPivot('Your_extra_data_on_pivot_table');
}
And by querying products, you can get category (which I suggest to be categories). You can retrieve it like this $products->first()->pivot->{name of_your_extra_data_on_pivot_table}
It is more optimized if you eager load this relationship.
EDITED: Guys can you review your suggested duplicate? I did some research before I ask this question, and I'm already to that link, that is not the answer that I'm looking for.
How can I pluck specific column in eloquent relationship? I want only name column to be returned when I Student::find()->subject;
I tried the below codes but doesn't work and returns me an error
App\Student::subject must return a relationship instance.
class Student extends Model
{
protected $table = 'subjects';
protected $fillables = ['id', 'name', 'gender', 'birthdate', etc.];
public function subject()
{
return $this->hasMany('App\Subject')->pluck('name');
}
}
You can use any query builder functions on the relation.
Use select to only select the name column
public function subject()
{
return $this->hasMany('App\Subject')->select('name');
}
I have a pivot table (builder_project) which I'm using on a many-to-many relationship between the 'projects' and 'builders' tables. And everything is working fine to this point.
However, I would like users to be able to add 'notes' to the pivot table (builder_project) and because many notes should be able to be added I created a table called 'notes' which has a one-to-many relationship with the pivot table.
I tried creating a model for the pivot table, however; when I try to access the method within the pivot model, I'm getting the following error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'notes.' in
'where clause' (SQL: select * from builder_project where exists
(select * from notes where builder_project.project_projectID =
notes.``))
This is the code for my pivot model:
namespace Estimating;
use Illuminate\Database\Eloquent\Relations\Pivot;
class Builder_project extends Pivot
{
protected $table = "builder_project";
protected $primaryKey = 'project_projectID'; // I need to add the other primary key here but I undestand it's not possible on Laravel
protected $fillable = [
'project_projectID',
'builder_builderID',
'note',
];
// One to many relationships
/**
*
*/
public function test()
{
return $this->hasMany('Estimating\Builder_project_note');
}
}
This is the model for Builder_project_note:
<?php
namespace Estimating;
use Illuminate\Database\Eloquent\Model;
class Builder_project_note extends Model
{
//Determines which database table to use, in this case 'projects' table
protected $table = "notes";
protected $primaryKey = 'noteID';
protected $fillable = [
'project_projectID',
'builder_builderID',
'note',
];
// One to many relationships
/**
* Get the status that owns the project.
*/
public function test()
{
return $this->belongsTo(
'Estimating\Builder_project'); // I know that here I need an ID from Builder_project pivot table - but I have a composite key!;
}
}
And this is how I'm trying to get the data from my controller and I get the error:
public function editBuilderProject(Request $request, $builderID, $projectID)
{
$browserDetails = new Agent();
$project = Project::find($projectID);
$builder = Builder::find($builderID);
$builder_project_statuses = Builder_project_status::all();
$builder_project_note = Builder_project::has('test')->get();
dd($builder_project_note);
return view('projects/edit-builder-project', compact('browserDetails', 'project','builder', 'builder_project_statuses', 'builder_project_note'));
//return $projectID." ". $builderID;
}
I would appreciate if anyone can point me to the right direction with this and my apologies if I'm not being clear enough - this is my first post here :)
I've uploaded a sample of my database model:
Database Model example
Laravel does not like primary keys based upon multiple columns. You need to add its own builder_project.id column (in your pivot table) which will be the field used by your notes table.
I have a model class with the name CourseSession and it's table is course_session, and I have another model named Student and it's table is student and every session has many students and also every student could be in many sessions. So I have created a third table named student_session with student_id, session_id, presence and laravels timestamp columns.
Creating a session needs to have a list of students and I get them from $request like this:
$validatedData = $request->validate([
'students' => 'required',
]);
students is array of students id!
this is my CourseSession model:
class CourseSession extends Model
{
protected $table = 'course_sessions';
protected $guarded = [];
public function course()
{
return $this->belongsTo('App\Course');
}
public function students()
{
return $this->belongsToMany('App\Student', 'student_session','session_id', 'student_id');
}
}
and this is my student model:
class Student extends Model
{
protected $guarded = [];
public function courses()
{
return $this->belongsToMany('App\Course');
}
public function exams()
{
return $this->belongsToMany('App\Exam');
}
public function sessions()
{
return $this->belongsToMany('App\CourseSession', 'student_session', 'student_id', 'session_id');
}
}
I create a session like this:
$session = new CourseSession();
$session->course_id = $course->id;
$session->save();
and I save students this way:
$sessions = $session->students()->create(['session_id' => $session->id, 'student_id' => 1, 'presence' => 1]);
but I get this error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'session_id' in 'field list' (SQL: insert into `students` (`session_id`, `student_id`, `presence`, `updated_at`, `created_at`) values (25, 1, 1, 2019-04-28 14:24:48, 2019-04-28 14:24:48))
according to error, it tries to write data on students table but I want to write them on student_session table!
what is wrong in my codes?
For this you want to use attach() instead of create().
$session->students()->attach(1, ['presence' => 1]);
In the above example 1 is the student_id. You don't need to specify the session_id as your calling this from a Session model. The array at the end is any additional data you want to add to the pivot table.
Since you have additional data in your student_session pivot table, it might also be an idea to add this to your belongsToMany relationships e.g.
public function sessions()
{
return $this->belongsToMany('App\CourseSession', 'student_session', 'student_id', 'session_id')
->withPivot('presence')
->withTimestamps();
}
This will include the presence and timestamps columns in the pivot data as well (obviously, you don't have to do this if you don't want to though).
I have 3 table on my database :
table 1 = user (hasMany order)
table 2 = order (hasMany order_detail, belongsTo user)
table 3 = order_detail (belongsTo order)
On my order_detail model i add this function :
public function order() {
return $this->belongsTo('App\Order');
}
so i can call the order data without define it from controller, i just define order_detail on my controller
$order_detail->order->invoice_number
but how to call the user data from the order detail?
I try use this
$order_detail->order->user
but it didn't work for me..
Is there any idea to call the grand parent relation?
In order model add function for order_detail:
public function order_details() {
return $this->hasMany('order_detail');
}
and for user:
public function user() {
return $this->belongsTo('user');
}
In user model add:
public function orders() {
return $this->hasMany('order');
}
Then, you can call in the controller:
$details = Order::find(1)->order_details->where('order_detail_id', 5)->first();
$userName = $details->username;
// ^
// column name in order_detail table
More info in the docs.
I think this is the more complete way to define the relationships:
// User model
public function orders(){
// I'm telling that users has many order. The orders have an user_id field that match with the ID field of the user.
return $this->hasMany('App/Order', 'user_id' , 'id');
}
// Order model
public function order_details(){
// I'm telling that order has many order_details. The order_details have an order_id field that match with the ID field of the order.
return $this->hasMany('App/OrderDetail', 'order_id' , 'id');
}
public function user(){
// I'm telling that an order belongs to an user. The user has an ID field that match with the order_id field of the order.
return $this->belongTo('App/User', 'id', 'user_id');
}
// OrderDetail Model
public function order(){
// I'm telling that an order detail belongs to an order. The order has an ID field that match with the order_id field of the order detail.
return $this->belongTo('App/Order', 'id', 'order_id');
}
I have seen that you put just the model name as first parameter in your relation definition. I think you must put the relative path from the root to the Model. In my case, I have the models as childs of the App folder.