Laravel relation with types - php

I have tried to find the best solution for my problem without getting exactly what i want.
I have 4 tables now, the structure looks like this.
:: Users ::
id
name
email
------
:: user_equipment ::
id
user_id
equipment_id
equipment_type
:: weapons ::
id
name
price
:: armor ::
id
name
price
My goal is to be able to use my relations like this:
$user->equipment
$user->equipment->weapons
$user->equipment->armor
Here is what i have right now:
User Model:
class User extends Model
{
public function equipment()
{
return $this->hasOne(UserEquipment::class);
}
}
UserEquipment Model:
class UserEquipment extends Model
{
public function weapons()
{
return $this->hasMany(Weapon::class);
}
}

First of all, your User model and UserEquipment model has the same class name.
Try this, change your user model to
public function weapons()
{
return $this->hasMany('App\Weapon', 'equipment_id')->where('equipment_type','weapon'); //second paramater tells what column to relate the id
}
public function armors()
{
return $this->hasMany('App\Armors', 'equipment_id')->where('equipment_type','armor');
}
Then here's how you query:
User::with('weapons', 'armors')->get();

This looks to me like a Many To Many Polymorphic Relationship.
In your case, you'll need to define your relationships this way:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* Get all of the weapons owned by the user.
*/
public function weapons()
{
return $this->morphedByMany('App\Weapon', 'equipment', 'user_equipment');
}
/**
* Get all of the armors owned by the user.
*/
public function armors()
{
return $this->morphedByMany('App\Armor', 'equipment', 'user_equipment');
}
}
Doing your queries:
$user = App\User::find(1);
foreach ($user->weapons as $weapon) {
//
}
foreach ($user->armors as $armor) {
//
}

Try to change your tables like this:
:: Users ::
id
name
email
------
:: user_equipment ::
id
user_id
equipment_type
:: weapons ::
id
name
price
user_equipment_id
:: armor ::
id
name
price
user_equipment_id
Then you can use the functions as you were using them:
User Model:
class User extends Model
{
public function equipment()
{
return $this->hasOne(UserEquipment::class);
}
}
UserEquipment Model:
class UserEquipment extends Model
{
public function weapons()
{
return $this->hasMany(Weapon::class);
}
public function armor()
{
return $this->hasMany(Armor::class);
}
}
Notice in laravel Documentation that Laravel assumes in the Model Weapons there would be a foreign key call user_equipment_id:
https://laravel.com/docs/5.7/eloquent-relationships#one-to-many

Related

Groupby on relation laravel

Hey i have three table like this
--table plan--
id
name
....
----table letter---
id
plan_id
....
---table person----
id
plan_id
name
.....
Model i have :
---Model plan---
class plan extends Model
{
protected $table = 'plan';
public function letter(){
return $this->hasOne('App\letter');
}
public function person(){
return $this->hasMany('App\person');
}
}
--Model person--
class person extends Model
{
public function plan(){
return $this->belongsTo('App\plan');
}
}
--Model letter--
class letter extends Model
{
public function plan(){
return $this->belongsTo('App\plan');
}
}
And in controller i write code like this :
$letter = letter::find($id) // $id from url parameter and it's work
return view('letter',['letter' => $letter]);
Nah in view i wanna acces person name from letter model as distinct , so i write code like this
{{ #foreach ($letter->plan()->person()->groupBy('name')->get) as $person }}
but it return error like this :
Call to undefined method Illuminate\Database\Query\Builder::person()
Where is my mistake(s)?
There is a difference between $letter->plan() and $letter->plan. If you call it like a method, Laravel will return the Query Builder. If you call it like an attribute Laravel will return the model from that relation.
So you're trying to call your model on the Query Builder, which is a method that doesn't exists and creates the error. This will fix your problem:
$letter->plan->person()->groupBy('name')->get()
In your controller you can do:
$letter = letter::find($id) // $id from url parameter and it's work
$persons = $letter->plan->person()->groupBy('name')->get();
return view('letter', compact('letter', 'persons'));
And in your view:
#foreach($persons as $person)

laravel 5.1 BelongsTo Reverse call

What i know:
$this->$parent->childs(); //we get childs data
what i want to know how:
$this->child->find($id)->parent(); //how to get childs parent without including model in controller | by just using eloquent
heres my sample code of employee and employeeDependent model:
trait EmployeeRelationships{
public function dependents(){
return $this->hasMany(\App\DB\EmployeeDependent\EmployeeDependent::class);
}
}
trait EmployeeDependentRelationships{
/**
* #return mixed
*/
public function employee(){
return $this->belongsTo(\App\DB\Employee\Employee::class, 'employee_id');
}
}
If you want to get the reverse of a BelongsTo relationship you need to specify the inverse of the relationship on the corresponding model. For example:
Employee Class
class Employee extends Model
{
public dependents()
{
return $this->hasMany(Dependant::class);
}
}
Dependent Class
class Dependent extends Model
{
public employee()
{
return $this->belongsTo(Employee::class, 'employee_id');
}
}
With these relationships defined you can then access the relevant models by calling the appropriate methods like so:
$dependents = Employee::first()->dependents; // Returns an eloquent collection
$employee = Dependent::first()->employee; // Returns a model of type Employee
Note that in this example using the first() method to grab a model, you can can do this with any object of the correct type.

one to many relationship in laravel

In my database, i have two tables notification and alertFrequency. The notification has field id and website_url and the alert frequency has id and notification_id. Both tables has models which is one to many. The notification can have one or many alertFrequency.
class Notification extends Model {
public function alertFrequencies() {
return $this - > belongsToMany('AlertFrequency::class');
}
}
namespace App;
use Illuminate\ Database\ Eloquent\ Model;
class AlertFrequency extends Model {
protected $table = 'alertFrequencies';
public function notification() {
return $this - > belongsTo(Notification::class);
}
}
in the notification model, i wrote a function called alert, that will give me the laastest alert associated with a specific websie.
public function alert(){
$alert_frequency = AlertFrequency::find('notification_id')->first();
$o_notification = $this->alertFrequencies()->where('notification_id',$alert_frequency->id)
->select('created_at')->orderBy('created_at')->first();
if($alert_frequency ==null){
return false;
}
return created_at;
}
Is this a right way to extract the data? i would appreciate any suggestions and helps?
Notification hasMany AlertFrequency
public function alertFrequencies(){
return $this->hasMany('App\AlertFrequency');
}
and,
$alert_frequency = AlertFrequency::with('notification')->orderBy('created_at','desc')->first();
loads the latest AlertFrequency along with it's notification.
See One to Many relationship and Eager loading in documentation.
to get laastest alert associated with a specific websie with url $website_url.
Notification::where('website_url', $website_url)->orderBy('created_at')->first();
hasMany relation :
public function alertFrequencies(){
return $this->hasMany('App\AlertFrequency','notification_id');
}

Laravel: How to make a relationship between two table that has a reference table

I have 3 tables.
People, Assignments and Projects
each person in People table can be assigned to one or more Projects.
Each project in Projects table can have one ore more person assigned to it.
Here are the columns of each table:
People
id
name
Assignments:
person_id
project_id
Projects
id
title
My question is: in my Project model, how do I define the relationship?
What I want is to be able to get the names of all person assigned to a specific project.
I NEED:
$project->assignedPeople
So I can:
foreach($projects as $project)
$project->title
foreach(projects->assignedPeople as $person)
$person->name
I NEED YOUR HELP PLEASE
THANK YOU!
Actually You need Many-to-Many relationship.
You can define the Models like this
Project Model
class Project extends Model {
public function peoples()
{
return $this->belongsToMany('App\People');
}
}
And
People Model
class People extends Model {
public function projects()
{
return $this->belongsToMany('App\Project');
}
}
Now you can access the names of all person assigned to a specific project like this.
$project->peoples
And you can run your foreach loop like this
foreach($projects as $project) {
echo $project->title;
foreach(project->peoples as $person) {
echo $person->name;
}
}
Hope it may solve your problem.
Thanks
// Inside Model Project
class Project extends Model {
public function people()
{
return $this->hasMany('App\Models\People');
}
}
// Inside Model People
class People extends Model {
public function project()
{
return $this->belongsToMany('App\Models\Project');
}
}
// In case of custom joining table:
class People extends Model {
public function project()
{
return $this->belongsToMany('App\Models\Project', 'Assignments', 'person_id', 'project_id');
}
}

Like or favorite a post with unique user using Laravel Eloquent

I was creating a like system for my website. in this I wanted one user can only like one time for a post. and a post can be liked by many user. Also many user can like many post.
So if I guess it right, It is a many to many reletionship.
in this context,
I create the following table
... users table:
id
name
....
posts table :
id
post
...post_likes table
id
user id
poost_id
Now I am having the following model for
user :
class User extends SentryUserModel {
public function post_likes()
{
return $this->has_many('Post_like', 'id');
}
}
post :
class Post extends Eloquent {
public function post_likes()
{
return $this->has_many('Post_like', 'id');
}
}
post_like :
class Post_like extends Eloquent {
public function posts()
{
return $this->belongs_to('Post', 'post_id');
}
public function users()
{
return $this->belongs_to('User', 'user_id');
}
}
now when I am going to insert into the database (for post_likes table) I am getting an error called
Illuminate \ Database \ Eloquent \ MassAssignmentException
user_id
Also I want to know is there any way to inset into database like
$user->like()->save($user); ?????
Thank you in advance. Happy coding . \m/
I'll start with a basic issue, firstly you might want to make sure all your tables are lower case (still as a snake case as well), it's not required but it's ultimately how it's expected to be with Laravel so it makes life easier to keep with that. Also a note to the wise, like Class names, database tables are typically in the singular so user instead of users
Secondly yes you can do an insert with $user->post_likes()->save($debate); as your post_likes method on the user class returns has_many.
Thirdly, your design of the Post_like class is a bit off, you could be better off make it like so:
class PostLike extends Eloquent { // note that PostLikes is a more standard naming for a class, they should ideally be camel case names but with all capitals for words
protected $table = 'post_like'; // specifies the table the model uses
public function post() // this should be singular, the naming of a belngs_to method is important as Laravel will do some of the work for you if let it
{
return $this->belongs_to('Post'); // by naming the method 'post' you no longer need to specify the id, Laravel will automatically know from the method name and just adding '_id' to it.
}
public function users()
{
return $this->belongs_to('User');
}
}
Fourthly, your other classes could be better as:
class Post extends Eloquent {
public function post_likes()
{
return $this->has_many('PostLike'); // doesn't require you to specify an id at all
}
}
I can't exactly tell you why you're getting that mass assign error, your post is a bit garbled and doesn't look like you've included the code that actually causes the exception? I have a feeling though is that you're trying to do an insert for multiple database rows at one time but haven't defined a fillable array for PostLike such as with here: http://four.laravel.com/docs/eloquent#mass-assignment
According to Laravel 5:
User Model:
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model {
public function post_likes()
{
return $this->hasMany('App\PostLike');
}
}
Post Model:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model {
public function post_likes()
{
return $this->hasMany('App\PostLike');
}
}
PostLike Model:
namespace App;
use Illuminate\Database\Eloquent\Model;
class PostLike extends Model {
protected $table = 'post_like';
public function posts()
{
return $this->belongsTo('App\Post');
}
public function users()
{
return $this->belongsTo('App\User');
}
}
and if you want to save the post_like data then:
$inputs['post_id'] = 1;
$inputs['user_id'] = 4;
$post_like = PostLike::create($inputs);
Hope this helps!!

Categories