Connect a table to many to many table - laravel

I have a many to many table from goods and companies and i want to connect it with a one to many table
company_good
+----------------+------------+
| company_ID | good_ID |
+----------------+------------+
| 1 | 1 |
| 2 | 1 |
| 2 | 2 |
+----------------+------------+
sales
+----------+----------------+--------------+----------+
| id | date | company_id | good_id |
+----------+----------------+--------------+----------+
| 1 | 2019-02-01 | 1 | 1 |
| 2 | 2019-02-01 | 2 | 1 |
| 2 | 2019-02-01 | 1 | 1 |
+----------+----------------+--------------+----------+
what i want to ask is are there any naming column on sales based on laravel rule? what i know is when a table posts want to connect it to table users the naming on table post should be user_id. but in this case how do i name it?

First off, you'll definitely want to use Eloquent for this.
The column names can be whatever you want them to be. When you set up a many to many model method you can define the related column names in there
Here's an extract from the Laravel documentation:
In addition to customizing the name of the joining table, you may also
customize the column names of the keys on the table by passing
additional arguments to the belongsToMany method. The third argument
is the foreign key name of the model on which you are defining the
relationship, while the fourth argument is the foreign key name of the
model that you are joining to:
return $this->belongsToMany('App\Role', 'role_user', 'user_id',
'role_id');
Read more at https://laravel.com/docs/5.8/eloquent-relationships#many-to-many

I suggest to add an id column to company_good table and name corresponding model as CompanyGood and instead of company_id and good_id in sales table use company_good_id column

Related

Laravel many to many 2 level down pivot table

I am trying to build a Survey Module in Laravel where user can create survey, assign questions and options to the questions in survey.
survey can have multiple questions
survey question can have multiple options
To meet the above requirement I created the following models & tables
Model: Question
Table: questions
| id | question |
| -------- | -------------------------|
| 1 | How is the performance? |
| 2 | How did you know about us|
Model: Option
Table: options
| id | option |
| --- | --------- |
| 1 | Good |
| 2 | Bad |
| 3 | Google |
| 2 | SMS |
Now the relationship between questions and survey will be stored in pivot table
Model: SurveyQuestion
Table: survey_questions
| id | survey_id| question_id |
| ---| -------- |-------------|
| 1 | 1 |1 |
| 1 | 1 |2 |
Upto this point I know how to store data into pivot table using attach/sync.
Now the problem is As per requirement each survey question might have multiple options so I created another pivot table survey_question_option in which I am using survey_questions primary key as foreign key.
Model: SurveyQuestionOption
Table: survey_question_options
| id | survey_question_id| option_id |
| -- | ----------------- |-----------|
| 1 | 1 |1 |
| 1 | 1 |2 |
Now my question is that is it correct to use pivot table primary key as foreign key into another table?
If yes then how can I store data into survey_question_options table using laravel relationships?
If no then what is the better solution?
In this case you can create a Custom Intermediate Table Model (Custom Pivot)
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Relations\Pivot;
class SurveyQuestion extends Pivot
{
public function options()
{
//You need to create a pivot pivot table survey_question_option
//with (survey_question_id, option_id)
return $this->belongsToMany(Option::class, 'survey_question_option');
}
}
Your models will need to recognize this new Pivot Model with the method using(). Here is an example with Survey Model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Survey extends Model
{
/**
* The users that belong to the role.
*/
public function questions()
{
return $this
->belongsToMany(Question::class)
->using(SurveyQuestion::class);
}
}
And them you will be able to access via eloquent like this
$survey->questions->pivot->options
For more information you can check the documentation here:
https://laravel.com/docs/8.x/eloquent-relationships#defining-custom-intermediate-table-models

How to get data from nested relationship in Laravel 8 Eloquent?

How to make a deep relationship with eloquent? I'm trying to display the data like this :
+------------------------------------+
| Main ID | Name | SN | Last Event |
|------------------------------------|
| 12 | James | j89 | RIGHT |
+------------------------------------+
The "Last Event" column is based on the latest data on "Tracks" table but the value "RIGHT" is relation between the "Tracks" table with "Events" table. So, in this table, the latest record in the tracks table is id of 9 with event_id of 12, the event_id of 12 in the Events table has name column that contained value RIGHT. That value that I want to grab it to display in front end. this is my table in database.
Main table
+---------------+
|id | name | sn |
|---------------|
|12 | James| j89|
+---------------+
Tracks table
+-------------------------------------+
|id | main_id | event_id | created_at |
|-------------------------------------|
| 5 | 10 | 10 | 2021-10-12 |
| 9 | 10 | 12 | 2021-11-20 |
+-------------------------------------+
Events
+----------+
|id | name |
|----------|
|10 | LEFT |
|12 | RIGHT|
+----------+
If I use has one relationship with latestOfMany() method, it didn't reach to the events table. How do I reach it to the Events table to grab the value in Events table through the latest data of Tracks table based on main_id? thanks!
you can use Eager Loading to load deep in your relation, if you setup your relation correctly:
class Main extends Model
{
public function latestTrack()
{
return $this->hasOne(Track::class,'main_id')->latestOfMany();
}
}
class Track extends Model
{
public function event()
{
return $this->belongsTo(Event::class,'event_id');
}
}
now you can get the structre you need:
$main=Main::with('latestTrack.event:id,name')->find(12);

Codeigniter 3 Joins in One table

I want to display the User Name Who created, but in the database the create name is in the form of int which is the id of the author.
How can I display the id to be the real name by using Join in one table.
Or if there is another way I will try.
For the table as below
+----+--------------+-------------+
| Id | user_create | name |
+----+--------------+-------------+
| 1 | Null | Admin |
| 2 | 1 | User |
+----+--------------+-------------+
and I want to display it like this
Detail User
Name : User
User Create : Admin
if I remember correctly the CI 3 syntax
$this->db
->select(['t1.name', 't2.name user_create'])
->join('thetable t2', 't2.user_create = t1.id', 'left')
->get('thetable t1');

Query data based on pivot table

I have a database design which essentially takes the following form (I have removed a lot of fields as they are not really needed for demonstration purposes). I have a users table
users
+----+---------------+-----------------+
| id | name | email |
+----+---------------+-----------------+
| 1 | ProjectA | Something |
+----+---------------+-----------------+
A user can have many projects
projects
+----+---------------+-----------------+-----------------+
| id | name | description | user_id |
+----+---------------+-----------------+-----------------+
| 1 | ProjectA | Something | 1 |
+----+---------------+-----------------+-----------------+
So that is straight forward enough and very easy to query. If I want all projects for the logged in user I can do
$loggedInUser = Auth::user()->getFirstName() . ' ' . Auth::user()->getLastName();
$loggedInUserId = User::where('userName', '=', $loggedInUser)->first();
$projectss = Project::all()->where('user_id', $loggedInUserId);
This is where things get a little more tricky. I have a pivot table for a users groups. It is essentially this
users_user_groups
+----+---------------+-----------------+
| id | user_id | group_id |
+----+---------------+-----------------+
| 1 | 1 | 2 |
+----+---------------+-----------------+
I then have a user_groups table
user_groups
+----+---------------+
| id | group_name |
+----+---------------+
| 1 | Group A |
+----+---------------+
If I want to find what groups a user is a part of I can do
$userGroups = Auth::user()->getGroups();
My question is this. Above, I demonstrate how I can get all projects for a user. Now I know there is a user_group called Group A. What I essentially want to do is get all projects where the user is apart of Group A. So if 5 users create a project and they are all in Group A, then I should be returned 5 projects.
How would I go about doing something like this?
Thanks
Firstly you can get user id using simply Auth::user()->id
Assuming you are trying to get all the projects that belongs to users of a group You can do this.
$group = Group::with('users.projects')->find(1);
Group model
public function users()
{
return $this->belongsToMany('App\User');
}
User Model
public function projects()
{
return $this->hasMany('App\Project');
}
Of course you would have to make the appropriate relation methods depending on the forign/primary keys you used.

DataMapper associates that depend on two columns

I have a table of products with attributes like SKU, Name, etc.
It seems like I need to have separate tables for each category of product due to the large variety of features depending on the category.
Say I have a table/class for boots, tools and hats
I'd like (unless there's a better way) to join/associate my products table to the other tables where appropriate (depending on category)?
Products Table
id | Name | SKU | Category(Table) | CategoryTableForeignKey
----------------------------------------------------------------------
1 | boot1 | 123 | Boots | 2
2 | knife1 | 345 | Tools | 42
-
Boots Table
id | product_id | Size | Width | Color | Sex
----------------------------------------------------------------------
2 | 1 | 9.5 | Wide | Olive | Male
-
Tools Table
id | product_id | length | Fixed | Coating | Etc
----------------------------------------------------------------------
42 | 2 | 4.5 | False | ... | ...
I'm not sure how to do this with DataMapper classes.
Ideally, I'd like to be able to:
my_boot = Boots.get(1)
my_boot.product.sku
Edit: dkubb pointed out a flaw in my code.
When you use has() what you're saying is that the foreign key is in the other model. If you want the foreign key to be in the table associated with the current model you want to use belongs_to.
class Product
include DataMapper::Resource
#descripe product properties ...
has n, :boots
end
Class Boot
include DataMapper::Resource
#describe boot properties ...
belongs_to :product
end
About DataMapper Associations: http://datamapper.org/docs/associations.html

Resources