Laravel getting data of logged in user from different tables based on foreign keys and id - laravel-5.4

Hi iam beginner of laravel ,i have four tables users,students,class,section
users
id
username
password
usertype
Students
id
name
roll no
class_id
section_id
class
id
class_name
sections
id
section_name
when i logged in getting user name and getting role no from student tables by using following method
User.php
public function getAttribute($key)
{$profile = student::where('stud_adm_id', '=', $this->attributes['username'])->first()->toArray();
foreach ($profile as $attr => $value) {
if (!array_key_exists($attr, $this->attributes)) {
$this->attributes[$attr] = $value;
}
}
return parent::getAttribute($key);
}
But i want to get class name and section name from related tables also to show logged in user complete profile....
and in view page called values as shown below
<h4>ID: {{ Auth::user()->roll_no}}</h4>
<h4>Name: {{ Auth::user()->name }}</h4>
Let me know how to get values of class and section also.

You can use Eloquent: Relationships.
Defining relationships in student.php
class Student {
...
public function class() {
$this->belongsTo('App\Class');
}
public function section() {
$this->belongsTo('App\Section');
}
...
}
Then you can retrieve the class and section relationship when you get the student model.
$student = Student::where('stud_adm_id', $username)->first();
$class = $studnet->class;
$section = $student->section;

Related

Eloquent retrieve data from another model on runtime

I have two tables;
Data
id
name
Custom_data
id
data_id (references id on Data)
customer_id (references id on Customers)
name
When I retrieve all items from the database (via for example Data::all()) as Customer X then I want to retrieve values from 'Custom_data' in favor of the data in table 'Data' where the customer_id matches X
Example:
Data contains name 'John Doe' with id 1
Custom_data contains a record with data_id 1 and name 'Jane Doe' and customer_id X
When retrieving the models I want to see Jane Doe instead of John Doe. Can this be done on a Model level in Eloquent? This is just a simple example, in our application we have multiple columns that need to be retrieved (firstname, lastname, street, etc. etc.)
How I am currently retrieving the fields is like this:
public function getNameAttribute($name) {
$customData = CustomData::where('customer_id', $this->customer_id)->where('data_id', $this->id)->first();
if(null != $customData) {
return $customData->name;
} else {
return $name;
}
}
Here' how you can do it:
In your Data.php modal file you need to add relationship:
public function CustomData(){
return $this->hasOne(CustomData::class);
}
Now, you can use CustomData function on eloquent record anywhere in Controller or View at runtime to get related data.
Another approach is to get data on condition basis:
$users = User::select('users.id', 'users.username', 'users.active', 'users.parent_id', 'parent.username as parent_username')
->selectRaw("CASE WHEN GROUP_CONCAT(roles.name) = 'student' THEN user_profiles.secondary_email ELSE users.email END as email");
I've used this type of solution for another purpose where I needed to use email on condition basis.
first you need to define relation in model
class DataModel extends Model{
...
public function customData()
{
return $this->hasMany(CustomDataModel::class,"data_id");
}
}
now you have access to this data.
$data = DataModel::with("customData")->first();
$data->name; // John Doe
$data->customData->name; // Jane Doe
Allright, I think I nailed this one.
I made a hasOne relation in my Data model:
public function custom_data() {
return $this->hasOne('App\Models\CustomData', 'data_id')->where('customer_id', $customer_id);
}
After that, I could fairly easily add the correct accessors like so:
public function getNameAttribute($name) {
return null != $this->custom_data ? $this->custom_data->name : $name;
}
If the custom data attribute has been set, we'll return that. If not, we'll return the original attribute.

Query multiple table relationships using Laravel Eloquent Models

I'm trying to query multiple tables using Laravel Eloquent Models with one to one, one to many and many to many relationships.
I have a forms table, a brands table a users table and a brand_groups pivot table.
Each form has one brand and one user:
forms
ID
user_id
brand_id
Brands do not have any foreign keys:
brands
ID
Users do not have any foreign keys:
users
ID
And there is a pivot table to create a many to many relationship for creating brand groups that have many users like brand members:
brand_groups
brand_id
user_id
I'm trying to get all the forms that belong to a user either by a direct ownership (forms.user_id) or by brand membership, all the forms from all the brands that the user is a member through brand_groups many to many pivot table.
For example, we have 2 brands, 2 users and 1 user is a member of 1 brand:
brand(ID: 1)
brand(ID: 2)
user(ID: 1)
user(ID: 2)
brand_group(brand_id: 1, user_id: 1)
form(ID: 1, user_id: 1, brand_id: null)
form(ID: 2, user_id: null, brand_id: 1)
form(ID: 3, user_id: 2, brand_id: 1)
form(ID: 4, user_id: 1, brand_id: 2)
Using Laravel Eloquent Models (not direct DB facade calls), I'd like to retrieve all the forms that belong to a user. For the user(ID:1) there are 3 forms:
form(ID:1) direct user ownership
form(ID:2) user is a member of brand(ID:1) group which is the brand of form(ID:2)
form(ID:3) user is a member of brand(ID:1) group which is the brand of form(ID:3)
I gave it a shot using Eloquent: Relationships - Has Many Through:
Has Many Through
The "has-many-through" relationship provides a convenient way to access distant relations via an intermediate relation.
I have tried it like this:
class User extends Model
{
public function forms()
{
return Forms::hasManyThrough(
Form::class,
BrandGroups::class,
'brand_id',
'brand_id',
'id',
'form_id',
)->where('id', $this->id);
}
}
But I get errors like:
BadMethodCallException with message 'Call to undefined method App\Models\Form::brand_groups()'
EDIT
After some digging, I have managed to come up with the working MySQL code that will return all the forms for a user:
SELECT * FROM `forms`
WHERE EXISTS (
SELECT `brand_id`, `user_id`
FROM `brand_groups`
WHERE `forms`.`brand_id` = `brand_groups`.`brand_id`
AND `brand_groups`.`user_id` = 1
) OR `forms`.`user_id` = 1
Now I just need to convert that query to an eloquent model relation.
Eloquent Models
User.php
class User extends Authenticatable implements MustVerifyEmail
{
public function brands()
{
return $this
->belongsToMany(Brand::class, 'brand_groups')
->using(BrandGroups::class)
->as('member');
}
public function forms()
{
return $this->hasMany(Form::class, 'user_id');
}
}
Brand.php
class Brand extends Model
{
protected $table = 'brands';
public function forms()
{
return $this->hasMany(Form::class);
}
public function members()
{
return $this
->belongsToMany(User::class, 'brand_groups')
->using(BrandGroups::class)
->as('member');
}
}
Form.php
class Form extends Model
{
protected $table = 'forms';
public function owner()
{
return $this->belongsTo(User::class);
}
public function brand()
{
return $this->belongsTo(Brand::class);
}
}
UPDATE
I manage to find a query to get all forms related to a user like this:
class User extends Authenticatable implements MustVerifyEmail
{
...
public function allForms()
{
return Form::where(function ($q) {
$q->whereExists(function ($q) {
$q->from('brand_groups')
->where('forms.brand_id', DB::raw('brand_groups.brand_id'))
->where('brand_groups.user_id', $this->id);
})->orWhere('owner_id', $this->id);
});
}
}
How this can be converted to a direct User model eloquent relationship?
Have you tried to Eager Load the User model relationships?
Edit
Firstly: the pivot table name should be the singular -snake_case- name of both tables and should be in alphabetical order (brand_user)
Next, try the following:
return User::where(‘id’, $this->id)->with([‘forms’,‘brands.forms’)->get();
This should return the Forms with direct ownership plus the user Brands and their associated Forms

Laravel: hasMany relationship + where condition fails

I have a Customer Eloquent model. Customer can have multiple WishLists where he / she can add some products. Typical ecommerce functionality.
The point is that Customer can belong to many Users models.
This was easy:
public function users()
{
return $this->belongsToMany(User::class, 'users_sync_customers', 'customer_uuid', 'user_id')
->withTimestamps()
->orderBy('last_name', 'asc');
}
So I can get all Customers assigned for logged in user by
auth()->user()->customers 🎉
As I mentioned, Customer can have multiple Wishlists:
public function wishLists()
{
return $this
->hasMany(WishList::class, 'customer_uuid', 'uuid')
->where('user_id', '=', auth()->user()->id); // <----- this will fail when I log out
}
but WishList is scoped to both Customer UUID and User ID.
Above relationship works but only when I'm logged in obviously.
As soon as I log out the auth()->user()->is is NULL and I get:
ErrorException {#1483 #message: "Trying to get property 'id' of
non-object"
Question: How can I reference in wishLists() the user_id value?
WishList model has this:
public function user()
{
return $this->belongsTo(User::class, 'user_id', 'id');
}
So can I use something like $this->user->id?
edit:
Nope, this also doesn't work.
you must check that the user is logged in?
Auth::check() ? Auth::user()->id : null

Yii2 hasMany relation with same table

Here is the scenario:
I have two tables:
family: id, name
person: id, name, familyId
The foreign key is on person (familyId -> family.id)
In my Person model i want to have a relationship that can include all the person entries that have the same familyId as the current person.
Essentially I want to do $person = Person::find([...])->with('family')->all() to get the current Person model, including an array of family members.
So far I have this on PersonModel:
public function getFamilyMembers()
{
return $this->hasMany(Person::className(), ['familyId' => 'familyId']);
}
...
$person = Person::find()
->with('familyMembers')
->where(['id'=>1]);
foreach($person->family as $m) {
var_dump($m);
}
I know I could do this with a junction table. But since it is a 1:n relationship I would like to avoid the extra Table.
Thanks.
The fast decision is something like this query in your person model :
public function getRelatedPersons()
{
return self::find()->jeftJoin(Family::tableName(), 'person.familyId =
family.id')->where(['person.familyId' => $this->familyId])->all();
}
...
foreach($personModel->relatedPersons as $person) {
var_dunp($preson);
}

cakePHP association data form add

I'm using a simple association where an Item is classified in a Category. At the same time, an Item is made by a Brand. Until now I have 3 entities: Item, Category and Brand. So, for example, in my Item table I'd have category_id = 1, brand_id = 1.
So, reading the documentation, I understood that I should do the following:
class Item extends AppModel {
public $hasOne = array('Category','Brand');
}
In the controller
public function add() {
$this->set('categories', $this->Item->Category->find('list'));
$this->set('brands', $this->Item->Brand->find('list'));
//...
In the View
echo $this->Form->input('name');
echo $this->Form->input('description');
//...
echo $this->Form->input('Category');
echo $this->Form->input('Brand');
The issue is that the MySQL query executed attemps to create a row with the name, description, but not the category or brand. It looks like INSERT INTO Item('name',description') VALUES(.... no category or brand at all.
What am I doing wrong?
You should change to
echo $this->Form->input('category_id');
echo $this->Form->input('brand_id');
The label names will still be Category and Brand, but the values will be saved
You should also change $hasOne with $belongsTo = array('Category','Brand');