laravel how to get all the users i talked to - php

i am now working on a messaging system with laravel. Now i want to have a list of users the current user send message to / receive from. suppose i have a message table like
id | sender_id | receiver_id | msg
1 | 1 | 2 | smadksamdksa
2 | 3 | 4 | hi
3 | 1 | 2 | www
4 | 2 | 1 | ssse
5 | 3 | 1 | hi
i find get a list of id of user i talked to, the result for the user 1 will be
id
2
3
model of message
namespace App;
use Illuminate\Database\Eloquent\Model;
class msg extends Model
{
protected $table = 'msgs';
public function user()
{
return $this->belongsTo('App\user');
}
}
the query i made
$senders = msg::select('sender_id')->where('receiver_id', '=', Auth::id())->distinct()->get();
$peopleUserTalkedTo = msg::select('receiver_id')->where('sender_id', '=', Auth::id())->distinct()->union($senders)->get();
but it doesn't work with an error
Undefined property: Illuminate\Database\Eloquent\Collection::$bindings
what's wrong with it, and can i SELECT sender id and receiver AS id, can i get the user id from it later on?
I think the problem is about the union method.

You should define your models like this:
namespace App;
use Illuminate\Database\Eloquent\Model;
class msg extends Model
{
protected $table = 'msgs';
public function sender()
{
return $this->belongsTo('App\user','sender_id');
}
public function receiver()
{
return $this->belongsTo('App\user','receiver_id');
}
}
namespace App;
use Illuminate\Database\Eloquent\Model;
class user extends Model
{
public function talkedTo()
{
return $this->hasMany('App\msg','sender_id');
}
public function relatedTo()
{
return $this->hasMany('App\msg','receiver_id');
}
}
Now try to fetch people you talked to like this:
Auth::user()->talkedTo()->get();
Auth::user()->relatedTo()->get();
Updated
For getting only ids of the people you talked to or related to follow the code:
Auth::user()->talkedTo->pluck('id');
Auth::user()->relatedTo->pluck('id');

didnt realy get what u want but Try this after being sure to add this to ur user model
class user extends Model
{
public function msgs()
{
return $this->hasMany('App\msg');
}
}
then
$mymsgs = Auth::user()->msgs->get(); //collection of all msgs
and then you can use a foreach loop

Related

Why extended class does not have the relationship in Laravel with Modules?

I have a Person class (App\Models\Person) and an Organization class (App\Models\Organization) which have a polymorphic relationship with User (App\Models\User). I am using Modules (nwidart/laravel-modules).
In my App\Providers\AppServiceProvider in the boot method I have this relationship:
Relation::morphMap(
[
'organizations' => 'App\Models\Organization',
'persons' => 'App\Models\Person',
]
);
Now, I have a module called Contracts, that module has a Person model (Modules\Contracts\Entities\Person) which extends from App\Models\Person. I also have a User model (Modules\Contracts\Entities\User) which extends from App\Models\User.
I added the following code to the ContractsServiceProvider boot method:
Relation::morphMap(
[
'persons' => 'Modules\Contracts\Entities\Person',
]
);
Now, if I go to any controller and I load a Person like this:
$person = \App\Models\Person::find( 1 );
The relationship with User doesn't exist, so I can't do $person->users()->first();
But if I load a Person like this:
$person = \Modules\Contracts\Entities\Person::find( 1 );
The relationship works like a charm.
The fun part is that all the relationship methods with users are inside the files User.php and Person.php in the app\Models directory.
In app\Models\User.php I have:
class User extends Authenticatable implements MustVerifyEmail {
public function usable()
{
return $this->morphTo();
}
}
In my app\Models\Person.php
class Person extends Model {
public function users()
{
return $this->morphMany( User::class, 'usable', 'usable_type', 'usable_id' );
}
}
Also, when I create an \App\Models\Userfrom an \App\Models\Person like this:
$person = \App\Models\Person::find( 1 );
$person->users()->create( [ ... ] );
The record in the database in the users table is like this:
+------------------------------------------------------------------------+
| id | email | usable_id | usable_type |
+------------------------------------------------------------------------+
| 1 | some#email.com | 3 | App\Models\Person |
+------------------------------------------------------------------------+
But if I create the user from a \Modules\Contracts\Entities\Person like this:
$person = \Modules\Contracts\Entities\Person::find( 1 );
$person->users()->create( [ ... ] );
The record in the database in the users table is like this:
+------------------------------------------------------------------------+
| id | email | usable_id | usable_type |
+------------------------------------------------------------------------+
| 1 | some#email.com | 3 | persons |
+------------------------------------------------------------------------+
I wonder if the ContractsServiceProvider is somehow overriding the AppServiceProvider and causing my relationship to fail. Any help would be appreciated.
Thanks

Laravel Eloquent returns an empty collection on belongsToMany relationship

UPDATE: The issue mentioned here has caused by the use of MariaDB instead of MySQL by XAMPP. I have followed the answer here to switch it to MySQL and it works like a charm.
This is regarding an e-commerce platform.
I have 2 data tables with 1 joining table for a many-to-many join. The idea is for Products to have many Special Offers running at any given time.
Tables
products
+-------+-------------------------------+
| id | name |
+-------+-------------------------------+
| 10001 | Apple iPhone 11 |
| 10002 | Samsung Galaxy S11 |
+-------+-------------------------------+
special_offers
+----+-------------------------------+
| id | name |
+----+-------------------------------+
| 1 | Awesome Offer |
| 2 | Year End Offer |
+----+-------------------------------+
product_special_offer
+------------+------------------+----------+
| product_id | special_offer_id | discount |
+------------+------------------+----------+
| 10001 | 1 | 10.0 |
| 10002 | 2 | 12.5 |
+------------+------------------+----------+
Models
Since the requirement is for a many-to-many relationship, I am using belongToMany method in my models.
Product
class Product extends Model
{
public function specialOffers()
{
return $this->belongsToMany(SpecialOffer::class)->withPivot('discount');
}
}
SpecialOffer
class SpecialOffer extends Model
{
public function products()
{
return $this->belongsToMany(Product::class)->withPivot('discount');
}
}
Controller
The following is the controller snippet.
ProductController
class ProductController extends Controller
{
public function index()
{
$product = Product::find(10001);
dd($product->specialOffers);
}
}
Results
The following is what Laravel returns.
Collection {#610 ▼
#items: []
}
The query it runs is mentioned below.
select `special_offers`.*, `product_special_offer`.`product_id` as `pivot_product_id`, `product_special_offer`.`special_offer_id` as `pivot_special_offer_id`, `product_special_offer`.`discount` as `pivot_discount` from `special_offers` inner join `product_special_offer` on `special_offers`.`id` = `product_special_offer`.`special_offer_id` where `product_special_offer`.`product_id` = 10001
This could work
class SpecialOffer extends Model
{
public function products()
{
return $this->belongsToMany(Product::class, 'product_special_offer','special_offer_id','product_id');
}
}
Make a third model to the connection table, and add the two relation. And it's will work.
class ProductSpecialOffer extends Model
{
public function products() {
return $this->belongsTo(Product::class);
}
public function specialOffers() {
return $this->belongsTo(SpecialOffer::class);
}
}

Laravel variable model polymorphic

I have a table as follows in my database:
table area_blocks;
id
owner_type
owner_id
created_at
updated_at
in the owner_type field it has the Eloquent Model name and the owner_id is the id of that model in the database. Example:
db: area_blocks
id | owner_type | owner_id
1 | App\Models\Title | 3
2 | App\Models\Title | 4
3 | App\Models\Textarea | 1
So I'm expecting when I fetch all of these to also eager load the relevant field from the eloquent model stored in owner_type.
Is there an eloquent relationship that can bring back that record from the owner_type field using eager loading? I've tried $this->morphTo(), e.g.
public function block()
{
return $this->morphTo();
}
but that is returned as null. Any ideas how this can be done?
Example code;
<?php
namespace App\Models;
use Cviebrock\EloquentSluggable\Sluggable;
use Illuminate\Database\Eloquent\Model;
class AreaBlocks extends Model
{
protected $with = ['block'];
public function block()
{
return $this->morphTo();
}
}
Route::get('/', function(){
return App\Models\AreaBlocks::all();
});
You have to specify the column name/prefix:
public function block()
{
return $this->morphTo('owner');
}
Or rename the relationship:
public function owner()
{
return $this->morphTo();
}

Laravel - model modifications

I need to refactor project and I have problem. Below is old, working model, where 'active' column is in "people" table. I need to move 'active' column into "people_translations" table.
Do you have any Idea to modify scopeActive method?
Thanks a lot!
Old working model:
class BaseModel extends Eloquent
{
public function scopeActive($query)
{
return $query->where($this->table . '.active', '=', 1);
}
}
class People extends BaseModel
{
protected $table = 'peoples';
protected $translationModel = 'PeopleTranslation';
}
class PeopleTranslation extends Eloquent
{
public $timestamps = false;
protected $table = 'peoples_translations';
}
Old tables structure:
Table: peoples
id | type | date | active
-------------------------
7 | .... | ... | 1
Table: peoples_translations
id | people_id | language_id | name
-----------------------------------
1 | 7 | 1 | Ann
Old query:
$peoples = \People::active()->get();
New tables structure:
Table: peoples
id | type | date
----------------
7 | .... | ...
Table: peoples_translations
id | people_id | language_id | name | active
--------------------------------------------
1 | 7 | 1 | Ann | 1
Create a relation for translations inside People Model
public function translations()
{
return $this->hasMany('PeopleTranslation', 'people_id');
}
Create active scope in People model
public function scopeActive($query)
{
return $query->whereHas('translations', function($query) {
$query->where('active', 1);
});
}
It will make subquery for this table and as a result it will get where (count of translations with active = 1) > 0.
If you have one-to-one relation - look for hasOne relation method instead of hasMany.

Insert relational models laravel eloquent

I am new to eloquent for laravel 4 and i can't quite figure out on how to make and save related models.
Table Messages: id | user | message | parent
For example:
class Message extends Eloquent {
public function user(){
return $this->belongs_to('User', 'id');
}
public function child(){
return $this->hasMany('Message', 'parent');
}
public function parent(){
return $this->belongs_to('Message', 'id')
}
}
So if you have a conversation you have a message, this message may or may not have a child or a parent and always has a user which made the message. So if i want to save a conversation this way, how would i do this?
For example, i have to following conversation:
John (1) says: Hi all!
Mark (3) responds: Hey there!
Hans (4) responds: Hi john
Peter(2) responds: Goodmorning.
Now i am john and i would like to save this conversation as below:
id | user | message | parent
========================================
1 | 1 | Hi, All! | NULL
2 | 3 | Hey there! | 1
3 | 4 | Hi john | 1
4 | 2 | Goodmorning. | 1
I can save them all separately but i figure there has to be a better way than below:
$parent = NULL;
foreach($messages as $message){
$model = new Message;
$model->user = $message['user'];
$model->message = $message['value'];
if(!is_null($parent)){
$model->parent = $parent;
}
$model->save();
if(is_null($parent)){
$parent = $model->id;
}
}
The initial problem I saw was that you are saying that the message's parent is always itself, you need to specify an additional unsigned integer to relate on. Here's one example:
public function parent(){
return $this->belongs_to('Message', 'parent_id')
}
You need to use that same 'parent_id' for the children as well:
public function children(){
return $this->hasMany('Message', 'parent_id');
}

Categories