How to select specific column in eloquent relationship inside the Model? - laravel

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');
}

Related

Model file name changes the table name in database

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

using '1' instead of user_id as second parameter to belongsTo

I have this situation where I want (hope/wish) to use a particular number e.g 1 directly as second parameter instead of using user_id. I was wondering if there was a to achieve this? or is it just not possible?
For example, currently I have relationship like this.
class orders extends Model
{
protected $tableName = 'orders';
protected $primarykey = 'id';
protected $fillable = [
'user_id',
'qty',
.
.
];
public function user()
{
return $this->belongsTo('App\User', user_id)->withDefault(['name' => 'N/A']);
}
But I was hoping if there was some way I can add another relationship like this?
public function main_user()
{
return $this->belongsTo('App\SpecialUser', 1)->withDefault(['name' => 'N/A']);
}
As can be see there is no column in this table that references SpecialUser table. However, I want a specific user to be accessed on that table using relationship.
I hope I am clear enough and sorry in advance for my newb way of explaining it because I am one.
Thanks in advance.
Please, try this code :
public function mainUser()
{
return $this->belongsTo('App\SpecialUser');
}
public function mainUserOne()
{
return $this->mainUser()->where('id', 1);
}
Controller :
Use App\Order;
$mainUser = (new Order)->mainUserOne()->first();

How to join two or more table using laravel eloquent method?

Little confused about eloquent-relationship joins, since I used to get the result by query builder so far. Referred with other related questions still, I am not clear. Please explain me with a better example.
Model 1 - customer
Model 2 - customer_items (relating customer_id and item_id)
Model 3 - items (details about items)
Now I want to list the item details that customer related to.
join customer_items with items where customer.id = customer_items.user_id and items.id = customer_items.item_id.
First define methods in models.
Customer.php // Customer model
class Customer extends Model
{
protected $table = 'customers';
protected $primaryKey = 'customer_id';
public function customerItems(){
//customer_id is a foreign key in customer_items table
return $this->hasMany(Item::class, 'customer_id');
// A customer will has many items thats why hasMany relation is used here
}
}
CustomerItem.php // CustomerItem
class CustomerItem extends Model
{
protected $table = 'customer_items';
protected $primaryKey = 'customer_item_id';
public function itemDetail(){
//customer_id is a foreign key in customer_items table
return $this->hasOne(Customer::class, 'customer_item_id');
//A Item will has single detail thats why hasOne relation used here
}
}
In CustomerController.php
use \Customer // define customer model path
public function getCustomerItem(Request $request)
{
// Eloquent query to get data
$customer_item_detail_data = Customer::with('customerItems.itemDetail')->get();
//it return all items of customers with item details
//$customer_item_detail_data = Customer::with('customerItems')->with('customerItems.itemDetail')->get(); you can also use in this way
}
Hope it helps. Thank you.
First, you would need to define your models as such:
class Customer extends Model
{
protected $table = 'customers';
public function items(){
return $this->hasMany(Item::class, 'customer_id');
}
}
class CustomerItem extends Model
{
protected $table = 'customer_items';
public function customer(){
return $this->belongsTo(Customer::class, 'customer_id');
}
}
Then you would call the the relationship as such:
$customer = Customer::find(1); // This will get the first customer in the DB
$itemsOfCostumer = $customer->items // This will return all the items of the customer
// Now let suppose we have an ItemCustomer and we would like to know the owner
$customerItem = CustomerItem::find(1); // Get the first item of a customer in DB
$customer = $customerItem->customer; // Ther you have the customer
This is just a small example. Stackoverflow is not an educational website which I would highly advise you to visit Laravel Relationship Docs. Over there you can learn much more and they have a really good series at Laracast about relationships (if you are visual learner) https://laracasts.com/series/eloquent-relationships
If I got well your question, you are looking for a query to get the item details.
$item_details = Items::
join('customer_items', 'customer_items.item_id', '=', 'items.id')
->join('customer', 'customer.id' '=', 'customer_items.customer_id');
Or you can get the same result doing:
$item_details = DB::table('items')
->join('customer_items', 'customer_items.item_id', '=', 'items.id')
->join('customer', 'customer.id' '=', 'customer_items.customer_id');

laravel use field in Eloquent model from another table

I have a model named "User". I want "Password" field from Eloquent from another table, and when user calls the user::all() method, all selected fields from different tables come in the result.
How can i do that?
Results are not displayed in with() .
my problem solved by using $appends in Eloquent model .
my code :
class User extends Eloquent {
protected $table = 'user';
protected $attributes = ['password'];
protected $appends = ['password'];
public function getPasswordAttribute()
{
return $this->getPAsswordMethod();
}
}
Your question is extremely board and borderline unanswerable but I will give you a board solution.
You are able to establish relationships to other tables via the Model objects you create. Lets pretend you have a Password table which belongs to the User.
User model:
public function password()
{
return $this->hasOne(Password::class, 'FK', 'PK');
}
You can now do User::with('password')->get(['FieldName']); and this will give you all of the passwords which have the above relationship to a user.

working with m:m relationships in eloquent outside laravel

I have been able to set up a m:m relationship in eloquent outside laravel and retrieve records but I have no idea how to add a new record as you dont create the pivot table in the code.
If these are my classes, how would i add a new instance to the M:M relationship between author and publisher?
<?php
include 'eloquent_database.php';
class Publisher extends Illuminate\Database\Eloquent\Model {
public $timestamps = false;
protected $table = 'publisher';
protected $primaryKey = 'publisher_id';
public function authors (){
return $this->belongsToMany('Author', 'author_publisher', 'publisher_id', 'author_id');
}
}
class Book extends Illuminate\Database\Eloquent\Model {
public $timestamps = false;
protected $table = 'book';
protected $primaryKey = 'book_id';
public function author() {
//related table name, pk in current table,
return $this->belongsTo('Author', 'author_id');
}
}
// Create the company model
class Author extends Illuminate\Database\Eloquent\Model {
public $timestamps = false;
protected $table = 'author';
protected $primaryKey = 'author_id';
public function books()
{
//related table, fk IN related table,
return $this->hasMany('Book', 'author_id');
}
public function publishers (){
return $this->belongsToMany('Publisher', 'author_publisher', 'author_id', 'publisher_id');
}
}
I would also need to know how to delete one too. I have seen this documentation http://laravel.com/docs/4.2/eloquent#working-with-pivot-tables but i dont really follow it
Id really appreicate an exxample of how to add and delete a new instance. Also onine there seeems to be so many different versions its hard to find which docs to follow as the code i have works but i didnt get it from the docs - just trial and error
Thanks a lot in advance
edit:
in repsonse to Rays comment i do have a pivot table in the database called author_publisher with author id and publisher id but i have no idea how to work with this pivot table. Do i have to create a class for it? I dont really understand
Here is a reference to said table in the code above
return $this->belongsToMany('Author', 'author_publisher', 'publisher_id', 'author_id');
When having a M:M relationship, make sure you have a table that translates the relationship between author and publisher. An example table could be composed of entries including both author_id and publisher_id. From what you have provided, you lack such a table.
There's another case if you do not have such a table. In order for such a M:M relationship to work, the author table must contain a column called "publisher_id" for simplicity. Likewise the publisher table must contain a column called "author_id". Then in the author model, return $this->hasMany('Publisher', 'author_id') and in the publisher model, return $this->hasMany('Author', 'publisher_id'). You should get the correct answer.

Resources