I'm having the following problem, I'm using scope in Laravel and I have the following relationship:
Enquiry
pickup_address
dropoff_address
Notes
This is referenced in the model:
public function pickup_address() {
return $this->belongsTo('App\Address', 'pickup_address', 'id');
}
I want to return the enquiry, as well as postcode which is stored in the Address table. I just want this column from this table and I have done the following:
return $query->with(['pickup_address' => function ($query) {
$query->select('postcode');
}])->get();
This gives the following (json):
{
"id":1,
"pickup_address":null
"notes":"hello world",
"created_at":"2017-06-08 09:56:52",
"updated_at":"2017-06-08 09:56:52"
}
This is not giving the postcode and just gives the pickup_address as null. However, removing the $query->select('postcode') gives:
{
"id":1,
"pickup_address": {
"id":140,
"house_number":null,
"address_1":"Address 1",
"address_2":null,
"postcode":"POSTCODE",
"city":"CITY",
"county":"C0UNTY",
"created_at":"2017-06-08 09:56:23",
"updated_at":"2017-06 0}",
"notes":"Hello world","
"created_at":"2017-06-08 09:56:52",
"updated_at":"2017-06-08 09:56:52"
}
However, I'm using Vue and using a table, so I just need the particular field to be returned that matches the column, rather than the entire object being returned.
Can anyone suggest a solution, please? I have followed some examples online and they suggest the $query->select('postcode')
Related
I am working with laravel 8 and have the following table with their models structure
Orders
Id, store_id,client_id,delivery_date,created_at
order_details
Id,order_id,product_id,quantity,total_price
Products,
Id,product_name,product_image
users
id,name,phone,address
I want to retrieve data from 4 tables according to order id to display order with it's details as following json format for example
{
"id":1,
"delivery_date":"20-06-2021",
"created_at":"10-06-2021",
"order_details":[
{
"id":1,
"product_name":"TV",
"product_image":"http://xxxx.com/images/tv.jpg",
"quantity":1,
"total_price":3000
},
{
"id":1,
"product_name":"playstation",
"product_image":"http://xxxx.com/images/playstation.jpg",
"quantity":3,
"total_price":5000
}
],
"client":{
"id":1,
"name":"john",
"address":"somewhere"
}
}
but I don't know how to get these data write code using relations and eloquent in laravel
Some basic idea to help you.
Orders Model
public function products(){
$this->belongsToMany(Product::class,'order_details')->withPivot('quantity', 'total_price')->withTimestamps();;
}
public function client(){
return $this->belongsTo(User::class,'client_id','id');
}
So you can do some think like below to access it
Order::with(['products','client'])->find($orderId);
Similar question but on relationship insert
Ref:Attempt to read property "price" on null in laravel?
Basically, I have three tables which are users, position, user_position and I want to get all users with their respective positions
Note that a single user can have multiple positions
The `user_position` table consists of:
- user_id
- position_id
To illustrate... it goes something like this:
users-->user_position<--position
What I got so far is this:
User Model
public function user_positions() {
return $this->hasMany('App\Models\UserPosition', 'user_id', 'id');
}
UserPosition Model
public function positions() {
return $this->hasMany('App\Models\Position', 'position_id', 'id');
}
UserController
public function getallusers() {
$data = User::with('user_positions')->get();
return response()->json($data);
}
So far it gives me the correct result set.
For example:
[{id:1,
name:'John',
user_positions:
[{id:1,
user_id:1,
position_id: 5
},
{id:2,
user_id:1,
position_id: 9
}
]
}]
However, it is incomplete, I also wanted the positions array inside the user_positions array but I don't know or I got lost on how to associate/merge/attach (i dont know the right term) the positions function to my User Model.
What you are looking for is a BelongsToMany relation.
You could add the following relation to your User model.
public function positions()
{
return $this->belongsToMany(Position::class);
}
You could eager load them with:
User::with('positions')->get();
Result:
[{
...
"positions": [{ ...The data of the position... }]
}]
When you want to m:m relation, it's advised to use BelongsToMany, there is no need for an intermediate model for the "pivoted" table.
If you have non-eloquent standard naming conventions. Then you have to specify the table name in the 2nd parameter as followed:
return $this->belongsToMany('App\Models\Positions', 'tbl_positions_assigned');
In the 3rd and 4th parameter you specify the foreign key names.
I'd like to refer to you to the documentation Eloquent-relationships as it's very thoroughly explained over there.
One very strong thing you can do with belongsToMany is to append extra columns in the pivot table. Those are also easily obtained from the pivot table. This is useful if you wish to store extra data values specific to the model.
return $this->belongsToMany('App\Models\Positions')->wherePivot('active', 1);
With above example you could exclude certain values, that are not active in this example, when you retrieve the results from the query.
I have two models
Post.php
id
post
show_id
type = 'movie' or 'tv'
Show.php
id // this only auto increment counter ids
show_id
show_type = 'movie' or 'tv'
the thing is show can be either tv or movie and may two with the same show_id for exmaple one tv could have a show_id of 10 and also one movie can have it but the types are diffrent
i have in post model
public function show(){
return $this->belongsTo('App\Show', 'show_id');
}
in show model
public function post(){
return $this->hasMany('App\Post', 'id');
}
this relationship get the first show with matching show id it sees, wheather its a movie or tv, i want to restrict it to match type column on both sides
post.php:
public function show() {
return $this->belongsTo('App\Show', 'show_id', 'show_id')
->where('type', $this->type);
}
show.php
public function posts() {
return $this->hasMany('App\Post', 'show_id', 'show_id')
->where('type', $this->show_type);
}
UPDATE (the code above does not work!)
Trying to use where clauses (like in the example below) won't work when eager loading the relationship because at the time the relationship is processed $this->f2 is null.
Read more here: Compoships
I just came accross a package https://github.com/topclaudy/compoships
what it does it allows creating relationships based on more than one FK, which laravel doesnt support by default
I think what you're looking for is a polymorphic relation. Instead of having a model that may be one of two "types" there should probably be two separate models on the same relation. For example:
class Post
{
public function Show()
{
return $this->morphTo();
}
}
class TvShow
{
public function Post()
{
return $this->morphMany('App\Post', 'show');
}
}
class Movie
{
public function Post()
{
return $this->morphMany('App\Post', 'show');
}
}
Then your posts table would have a show_id and show_type field that would relate to either a tv show or movie. Check out the docs for more info, I'm not sure of the rest of your project so I'm not 100% this will fit but anytime you start putting "_type" fields in your table you should question whether or not you should be using a polymorphic relation. This will also likely keep your models cleaner and free of a bunch of if statements as you realize there are other differences between movies and shows and how you handle them.
https://laravel.com/docs/5.7/eloquent-relationships#polymorphic-relations
how can i merge laravel relationship results in to one object?
MyController.php
public function getUser($id) {
return TournamentUser::where('customer_id','=', $id)->with('user')->get();
}
MyModel.php
public function user() {
return $this->hasOne('App\Models\Customer','customer_id', 'customer_id');
}
returning result :
[{
"id":1,
"tournament_id":3,
"customer_id":2016827550,
"point":0,
"user":{
"id":1,
"customer_id":2016827550,
"nickname":"OMahoooo"
}
}]
as expected query returns user section as array but i expect result like this :
[{
"id":1,
"tournament_id":3,
"customer_id":2016827550,
"point":0,
"nickname":"OMahoooo"
}]
only get nickname section without user array. I hope you understand me.
Sorry for my english , have a nice day
You can load the data and remap it manually using map() method. I've just tested this code and it works perfectly with hasOne() relationship:
$users = TournamentUser::where('customer_id', $id)->with('user')->get();
$users->map(function ($i) {
$i->nickname = $i->user->nickname; // Set related nickname.
unset($i->user); // Delete user data from the collection.
return $i;
});
Alternatively, you could use an accessor, but in this case, you'll meet the N+1 problem.
I have 3 tables as follow
dealer
id - dealer_name
specialties
id - name
dealer_specialty
id - dealer_id - specialty_id
So Dealer and Speciality model have many to many relation ship so in their models they looks like
Dealer.php
public function specialties()
{
return $this->belongsToMany('App\Models\Specialty');
}
In Speciality.php
public function dealers()
{
return $this->belongsToMany('App\Models\Dealer');
}
Now I have a scenario, where user can filter the result. Like at first whole dealers table will be shown. Now user can filter result with specialties and dealer name. So I have made route with optional parameters. And on my controller I am checking if param ins't empty put a where condition. Its working only with dealer_name as its where condition is referring to its own table. I got problem when I need to put where condition with specialty table.
My code looks like
$dealerArray = DB::table('dealers');
if(!empty($speciality )) {
// how to put where condition like get all dealers with specialit id 4, if this condition matches. I have tried following but its definitely generating error.
$dealerArray->specialities()->where('blah blah blah');
//I have also tried whereHas..
}
if(!empty($keyword)) {
$dealerArray->where('dealer_name','Like','%'.$keyword.'%');
}
return $dealerArray->get() ;
So finally I want to know how can I put an option condition that If I have to filter dealers from specialty id, how can I do that.
Try this one
In the Dealer.php
public function specialties()
{
return $this->belongsToMany(Speciality::class, 'dealer_specialty', 'dealer_id', 'specialty_id');
}
In Speciality.php
public function dealers()
{
return $this->belongsToMany(Dealer::class, 'dealer_specialty', 'specialty_id', 'dealer_id');
}
Query
$dealerArray = new Dealer();
if (!empty($speciality)) {
// how to put where condition like get all dealers with speciality id 4,
// if this condition matches. I have tried following but its definitely generating error.
$dealerArray = $dealerArray->whereHas('specialties', function ($query) use ($speciality) {
$query->where('specialty_id', $speciality);
});
//I have also tried whereHas..
}
if (!empty($keyword)) {
$dealerArray = $dealerArray->where('dealer_name', 'Like', '%' . $keyword . '%');
}
return $dealerArray->get();