So, Iam trying to make a conversation/message system.
So I have a problem right now. When I use the following line, I get [] (Empty Json):
$this->auth->user()->conversations
User model:
public function conversations()
{
return $this->belongsToMany(\App\Models\Conversation\Conversation::class);
}
But if I use this line, I get data that I want:
$this->auth->user()->messages()->first()->conversation->messages
Also when a line like the following one is used, I get an error
Property [conversation] does not exist on this collection instance.
$this->auth->user()->messages->conversation->messages
Here are Messages model line:
public function conversation()
{
return $this->belongsTo(\App\Models\Conversation\Conversation::class);
}
Here are User model line:
public function messages()
{
return $this->hasMany(\App\Models\Conversation\Messages::class);
}
Here are My database schema:
So my question is, do I do something wrong here or this is just some kind of bug? Thanks for any answers/help.
Related
hi i have many to many polymorphic Relation
When I use the sync method to insert data in the interface table, I encounter this error. What is the problem?
controller code:
$job_create->skills()->sync($request['skill']);
job model:
public function skills(){
$this->morphMany(Skil::class,'skillables');
}
skill model:
public function jobs()
{
return $this->morphedByMany(Job::class, 'skillables');
}
first make sure that given Skil::class is correct i think it must be Skill::class
public function skills(){
return $this->morphMany(Skill::class,'skillables');
}
the error says that $job_create->skills() is null you can test it with dd();
dd($job_create->skills()->get());
if the problem didn't solved just study the documentation:
https://laravel.com/docs/9.x/eloquent-relationships#many-to-many-polymorphic-relations
Relationships should always return the relation.
public function skills(){
return $this->morphMany(Skil::class,'skillables');
}
I got a weird problem I can't handle with. I got a simple Shop Application in Laravel and Vue/Vuex for frontend.
My Order model has a hasMany relationship:
public function items()
{
return $this->hasMany(OrderItem::class);
}
and it's fine.
I'm making a GET /orders/ request from vuex action to fetch orders from Laravel. This is my OrderController#index action:
// Return JSON response if wantsJson otherwise just show View.
if ($this->request->wantsJson()) {
$orders = Order::with(['client', 'items'])->orderBy('id', 'desc')->get();
return response()->json($orders);
}
return view('panel.orders.index');
As we can see below it worked as excepted - returned JSON response with orders.
Each order has a two $appends fields: total_net & total_net_after_discounts and its methods: getTotalNetAttribute() & getTotalNetAfterDiscountsAttribute().
For $appends calculations I need an items relationship items. So inside getTotalNetAttribute() method I'm trying to get a relation items:
public function getTotalNetAttribute()
{
$items = $this->items;
}
When I just add $this->items into method I got a response: ERR_CONNECTION_RESET. My whole response is broken after that. I can't even log it:
public function getTotalNetAttribute()
{
logger($this->items); // it just breaking up my response: ERR_CONNECTION_RESET
}
Another weird thing is that it's working in tinker. I mean I can use $this->items, sum their prices and get $order->total_net value with no problems.
EDIT:
I found a workaround:
public function getNetPriceAttribute()
{
$orderItems = $this->hasMany(OrderItem::class)->get();
return $orderItems->sum(function ($item) {
return $item->net_price;
});
}
UPDATED:
I'm trying to add my own attribute with subquery results to the results of main query.
Now, I have Many-To-Many relation between three tables: Tournaments, Participants and Users.
Here is the defining of relation in Tournaments model:
public function users() {
return $this->belongsToMany('App\User', 'Participants', 'Id_tourn', 'Id_user')->withPivot('Rating');
}
The structure of tables is:
Users:
-Id
-Name
Participants:
-Id
-Id_user
-Id_tournament
-Final
-Final_place
Tournaments:
-Id
-Name
I need to have extra Winners attribute in my final query result where I'll have info of first three places.
Following the documentation, I've created an accessor and tried different variants:
That just freeze the system. Nothing happenes and in 30 second I get timeout error.
public function getWinnersAttribute() {
return Tournaments::where("Id","=",$this->attributes['Id'])->where("Finals","=",1)->limit(3)->orderBy("Final_place","asc")->get();
}
This returns an error that "finals" column is not fount in Tournaments table, so $this doesn't have relation:
public function getWinnersAttribute()
{
return $this->where("Finals","=",1)->limit(3)->orderBy("final_place","asc")->get();
}
This returns blank white page without anything:
public function getWinnersAttribute()
{
return $this->with('users')->where("Finals","=",1)->limit(3)->orderBy("final_place","asc")->get();
}
This return "Winners" attribute empty:
public function getWinnersAttribute()
{
return $this->with("users")->where("Finals","=",1)->limit(3)->orderBy("final_place","asc");
}
I've created $appends variable to apply the accessor: protected $appends = ['Winners'];
However, I've checked the accessor, it works. If I return just:
public function getWinnersAttribute()
{
return "123";
}
it works fine and I get "123" inside "winners" attribute of main query result.
The main query is:
Tournaments::with(['users'])->get();
The Finals column is in pivot table of Many-To-Many relation.
UPDATED:
When I try to return query to that Model without relation:
public function getWinnersAttribute($value)
{
return $this->where("Finals",'=',2);
}
I get nothing in winners attribute as well. Like the subquery is not executed.
And if I add get() in the end of return:
return $this->where("Finals",'=',2)->get();
I get blank white page.
How can I solve that problem?
Thanks a lot.
If the getWinnersAttribute is on the Tournament model that means you already have a Tournament model you are calling by doing for example Tournament::find(1)->winners In your attribute you are trying too find the model again, and that could make it a forever loop trying to find a new one already having one etc. try using $this instead
public function getWinnersAttribute()
{
return $this->where("finals","=",1)->limit(3)->orderBy("final_place","asc")->get();
}
I have this relationship on eloquent
public function Manufacturer() {
return $this->hasOne('App\Models\ManufacturerModel', 'id')->select('name');
}
And this returns correctly the manufacturer name:
{"id":1,"serialnumber":"123_1","buydate":"2018-01-26 00:00:00","offservice":null,"deleted":"0","manufacturer":{"name":"HP"}}
I want to retrieve the name not as JSON object but as a string
{"id":1,"serialnumber":"123_1","buydate":"2018-01-26 00:00:00","offservice":null,"deleted":"0","manufacturer":"HP"}
The best way to define the relationship is:
public function Manufacturer() {
return $this->hasOne('App\Models\ManufacturerModel', 'id');
}
Then you can get the manufacturer name this way:
$your_object->manufacturer->name;
Or adding a wrapper method:
public function ManufacturerName() {
return $this->manufacturer->name;
}
Notice that when you refer to the relationship without parenthesis the query is executed and what you are accessing is the result. If you don't want the entire record to be queried you can do this:
public function ManufacturerName() {
return $this->manufacturer()->select('name')->get()->name;
}
By accessing the relationship with parenthesis you are getting the relationship definition and you can modify it before executing the query.
Not directly but you can achieve the functionality using a little bit trick of php, for example, if you would like to use it in string context as given below:
// {{ $someModel->manufacturer }}
echo $someModel->manufacturer; // or echo Manufacturer::find(1);
Then you can do it using the __toString magic method in Manufacturer model as given below:
public function __toString()
{
return $this->name;
}
In this case, even on json_encode($manufacturer) will give you just name so why don't you just use $model->manufacturer->name;
I try to define a custom Model method in Laravel. I have a n:m relation between Subscription and Notification over SubscriptionNotification.
I already defined the default relations:
public function subscription_notifications() {
return $this->hasMany('App\SubscriptionNotification');
}
public function notifications() {
return $this->belongsToMany('App\Notification', 'subscription_notifications');
}
Now I want to define a method, which returns a collection of notifications. I collect the IDs of the notifications I want in an array and write the following method:
public function notifications_due() {
// Collect $notification_ids
return $this->belongsToMany('App\Notification', 'subscription_notifications')->whereIn('notifications.id', $notification_ids)->get();
}
But when I want to use the mothod by $subscription->notifications_due, I get the following error:
[LogicException]
Relationship method must return an object of type Illuminate\Database\Eloquent\Relations\Relation
I'm new to Laravel (I come from Rails). I don't know if this is in Laravel even possible. Maybe someone can help me. Thanks!
Remove the ->get() part in the method notifications_due. get() will return a Collection, but when calling the method as a property (or magic method), Laravel expects the method to return an instance of Relation. Laravel will then execute the query and transform it to a Collection automatically.
Also, you can use your already defined notifications() method:
public function notifications_due() {
// Collect $notification_ids
return $this->notifications()->whereIn('id', $notification_ids);
}
Remove the get call from your relationship method, for example:
public function notifications_due() {
return $this->belongsToMany(
'App\Notification',
'subscription_notifications
')->whereIn('notifications.id', $notification_ids);
}
Use it just same:
// It'll return a collection
$dues = $subscription->notifications_due;
To get all the ids from the collection you may try this:
$ids = $dues->pluck('id');
Also, you may add more constraints if you want if you use it like:the
$dues = $subscription->notifications_due()->where('some', 'thing')->get();
Or paginate:
$dues = $subscription->notifications_due()->where('some', 'thing')->paginate(10);