Many to Many Relationship Laravel 5.2 - laravel

class Quotation extends Model
{
public function users(){
return $this->belongsToMany('App\User', 'quotations_users', 'quotation_id', 'user_id');
}
}
class User extends Authenticatable
{
public function quotations(){
return $this->belongsToMany('App\Quotation', 'quotations_users', 'quotation_id', 'user_id')->withTimestamps();
}
}
$quotation = Quotation::where('searchable_key', '=', $searchKey)->first();
$quotation = Quotation::find($quotation->id);
dd($quotation->users());
This code works well but how can I get the name of the user? I used dd($user->users->name) but it didn't work.

Related

How to elegantly use a remote one-to-many like association on a many-to-many in Laravel

For example, there are four models as follows.
class User extends Authenticatable
{
public function orders(): MorphMany
{
return $this->morphMany(Order::class, 'orderable');
}
}
class Partner extends Model implements Authenticatable
{
public function orders(): MorphMany
{
return $this->morphMany(Order::class, 'orderable');
}
}
class Order extends Model
{
public function orderable(): MorphTo
{
return $this->morphTo();
}
public function projects(): BelongsToMany
{
return $this->belongsToMany(Project::class)->withPivot('amount', 'price');
}
}
class Project extends Model
{
public function orders(): BelongsToMany
{
return $this->belongsToMany(Order::class)->withPivot('amount', 'price');
}
}
User、Partner and Order are one to many polymorphic relations。
Order and Project are many to many relations。
How to elegantly get all projects enrolled by a given user?
Thanks!

Relationship through one model

I have three tables - users, properties, devices.
users
id
name
properties
id
name
user_id
devices
id
name
property_id
How to define straight relationship to user model from devices model?
class Device extends Model
{
public function user()
{
return $this->....();
}
}
Is it possible to define such relation? Thanks.
Make sure to set all relation in other classes.
class Property extends Model
{
public function user()
{
return $this->belongsTo('App\User');
}
}
class Device extends Model
{
public function property()
{
return $this->belongsTo('App\Property');
}
public function user()
{
return $this->belongsTo('App\User', null, null, 'property');
}
}
You can provide a relation with in 4th parameter of belongsTo method.
//user model
public function role()
{
return $this->belongsTo('App\Role');
}
public function employee()
{
return $this->hasMany('App\Employee');
}
//role model
public function users()
{
return $this->hasMany('App\User');
}
//employee model
public function users()
{
return $this->belongsTo('App\User');
}
//value show using tinker command in command promote
App\User::find(1)->employee;
App\User::find(1)->role;
I think I have found the solution, this is what I end up with.
class Device extends Model
{
public function user()
{
$instance = new User();
$instance->setTable('properties');
$query = $instance->newQuery();
return (new BelongsTo($query, $this, 'property_id', $instance->getKeyName(), 'property'))
->join('users', 'users.id', '=', 'properties.user_id')
->select(DB::raw('users.*')
);
}
}
Hope this will be of help for somebody.

How to display owner of a post in laravel admin list display?

public function index()
{
$query = Activity::orderBy('id','DESC')->with('provinces');
if(!Auth::user()->hasRole('Administer')){
$query=$query->where('province_id', Auth::user()->id);
}
$activities = $query->latest()->get();
return view('activity.index',compact('activities'));
}
How to display owner of a post in laravel admin list display?
My User Model
class User extends Authenticatable implements HasMedia
{
public function activities()
{
return $this->hasMany(Activity::class);
}
}
My Activity Model:
class Activity extends Model
{
protected $guarded = [];
public function user()
{
return $this->belongsTo(User::class);
}
public function provinces()
{
return $this->belongsToMany(Province::class);
}
}
My province Model
class Province extends Model
{
protected $fillable = [ 'title', 'post_id'];
public function activities()
{
return $this->belongsToMany(Activity::class);
}
public function user()
{
return $this->belongsToMany(User::class);
}
}
I want to show the content to the user by province.
And also the admin can see all the content.
please help me i am new in laravel
Based on your comment, you should change your province conditions to:
if (!Auth::user()->hasRole('Administer')) {
$query = $query->where('province_id', Auth::user()->province_id);
}
You have defined that each activity belongs to an user. So can access owner of each activity like this:
$activity->user->name;
And if your activity belongs to a province, you should define your relation in this way:
class Activity extends Model
{
protected $guarded = [];
public function user()
{
return $this->belongsTo(User::class);
}
public function province()
{
return $this->belongsTo(Province::class);
}
}
Also for your Province model:
class Province extends Model
{
protected $fillable = [ 'title', 'post_id'];
public function activities()
{
return $this->hasMany(Activity::class);
}
public function users()
{
return $this->hasMany(User::class);
}
}
And this is best practice to use eager loading for fetching related records. It will look like this one:
$query = Activity::with(['user', 'province'])->orderBy('id','DESC');
Also another hint: try to use better variable names. You can use $activities instead of $query.

How in laravel to make a deep HasManyThrough?

I created a relationship like this:
Type.City.Street.House.Apartment
In this relation, the apartment must depend on the House and on the Type at the same time, so result sql query must be like this:
select * from `apartments` where `apartments`.`house_id` in ('1', '2', '3') and `type_id` = '777'
The problem is that the HasManyThrough relationship only looks at a two of levels and it's not possible to get to the very first model with it.
Please, advise how this can be done?
My models definations:
class Type extends Model {
public function city() {
return $this->hasMany('App\City');
}
}
class City extends Model {
public function street() {
return $this->hasMany('App\Street');
}
}
class Street extends Model {
public function house() {
return $this->hasMany('App\House');
}
}
class House extends Model {
public function Apartment() {
return $this->hasMany('App\Apartment');
//->where('type_id', '=' type.id) ?????
}
}
class Apartment extends Model {
public $fillable = ['house_id', 'type_id']
}
I would add a mapping for house_id in Apartment model and sets bidirectional mappings among your models
class Apartment extends Model {
public $fillable = ['house_id', 'type_id'];
public function house() {
return $this->belongsTo('App\House', 'house_id');
}
}
class Type extends Model {
public function city() {
return $this->hasMany('App\City');
}
}
class City extends Model {
public function type() {
return $this->belongsTo('App\Type', 'type_id');
}
public function street() {
return $this->hasMany('App\Street');
}
}
class Street extends Model {
public function city() {
return $this->belongsTo('App\City', 'city_id');
}
public function house() {
return $this->hasMany('App\House');
}
}
class House extends Model {
public function street() {
return $this->belongsTo('App\Street', 'street_id');
}
public function Apartment() {
return $this->hasMany('App\Apartment');
//->where('type_id', '=' type.id) ?????
}
}
then you can query apartments as per your criteria like
Apartments::whereHas('house.street.city.type', function ($query) use ($type_id) {
$query->where('id', '=', $type_id);
})
->whereHas('house', function ($query) use ($house_ids) {
$query->whereIn('id', $house_ids);
});
And i guess there is no need for type_id in Apartments model
I created a HasManyThrough relationship with unlimited levels: Repository on GitHub
After the installation, you can use it like this:
class Type extends Model {
use \Staudenmeir\EloquentHasManyDeep\HasRelationships;
public function Apartment() {
return $this->hasManyDeep(Apartment::class, [City::class, Street::class, House::class])
->where('apartments.type_id', $this->id);
}
}
Unfortunately, this doesn't work with eager loading.

Laravel 5: Relations through several tables

I have the following models: Merchant, Product and Store:
Merchant:
class Merchant extends Model
{
public function products() {
return $this->hasMany('App\Product');
}
}
Product:
class Product extends Model
{
public function merchants() {
return $this->belongsTo('App\Merchant');
}
public function stores() {
return $this->belongsTo('App\Store');
}
}
Store:
class Store extends Model
{
public function products() {
return $this->hasMany('App\Product');
}
}
In my MerchantController, I have the following method show():
public function show() {
$merchants = Merchant::selectRaw('merchants.*, REPLACE(abstract, \'[[name]]\', name) AS abstract')
->with('products')
->where('active', 'yes')
->Paginate(10);
dd($merchants);
//return view('merchants', compact('merchants'));
}
How can I access the stores, the several products are in? I tried ->with(['products', 'stores']) and got an error:
Call to undefined relationship [stores] on model [App\Merchant].
What can I do to solve my problem?
Use laravel's hasManyThrough relationship
in your Merchant model
add this relationship
public function stores()
{
return $this->hasManyThrough(Store::class, Product::class);
}

Resources