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