I have the following data structure in my laravel application
user_comments
id - integer
name - string
created_at - timestamp
user_actions
id - integer
name - string
created_at - timestamp
users
id - integer
name - string
user_history
user_id - integer
history_id - integer
history_type - string
And my App\Models\User contains the following relationships
/**
* Get all of the comments that are associated with this user.
*/
public function comments() : BelongsToMany {
return $this->belongsToMany(UserComment::class, 'user_history', 'user_id', 'history_id')->where('user_history.history_type', 'comment');
}
/**
* Get all of the actions that are associated with this user.
*/
public function actions() : BelongsToMany {
return $this->belongsToMany(UserAction::class, 'user_history', 'user_id', 'history_id')->where('user_history.history_type', 'action');
}
My aim is to be able to get each history type separately when I need it, but then be able to get all of the users history together, as a combined history trail of everything the user has done in the order it was done, so I can loop through and print out a history log.
At the moment the only way I can think of is by getting each of the relationships, merging the collections and sorting by created_at DESC, which is working fine, but in a perfect world, I would like to make 1 relationship (maybe polymorphic?) that just gets the actions and comments pivots together as 1 big collection.
As far as i'm aware, I cant UNION in the database as the tables have different column counts (and I need all the data from each table).
Is there a way to do this neatly using relationships to get the database to do the legwork, rather than having to get the relationships separately and merge/sort them?
Going forward there will be more pivot relationships like user_photos, user_emails, etc, so 1 neat way to get them all would be perfect!
Whenever you need interact with a pivot table, you can create a pivot model and use it as a normal model, or you can write a DB statement that will get the data. I like the model way better.
class UserHistory extends Pivot
{
// since Pivot extends Model
// this just a normal model
// with Pivot specific stuff.
}
DB statement can be something like this:
DB::select('select * from user_history');
Related
In this figure, the remaining tables are linked to the datainfo table. I need to retrieve the entire table data from the datainfo table.
In this picture I have shown the tables themselves
You can create Eloquent Models for each table and define Relationships among them. This is the Correct Laravel Way.
Let's assume Your datainfo table represents your Datainfo model,
Your cars table represents Car model. Same as washtypes and boxes.
then depending on your relation type defined the relation in Datainfo model.
class Datainfo extends Model
{
public function cars()
{
return $this->hasMany(Car::class);
}
}
You also can use hasOne instead of hasMany for one - to one relation
Similarly, create relation defining functions as washtypes() and boxes().
Then To get Datainfo with all related data using something like think in your controller
return Datainfo::with('cars','washtypes','boxes')->get();
Alternatively, you can get the count
return Datainfo::with('cars','washtypes','boxes')->count();
To get a count on a date
return Datainfo::with('cars','washtypes','boxes')->where('created_at',$date_var)->count();
If you only want Datainfo that has relation with cars, washtypes or boxes:
return Datainfo::has('cars','washtypes','boxes')->where('created_at',$date_var)->count();
Use laravel eloquent join clauses, https://laravel.com/docs/8.x/queries#joins
For total amount in same day
You can use eloquent sum and group by methods based on the date
i have problem in laravel. i have created multiple morph in one table.
table structure
table_name : morphicable
id:
model_id: eg: '1'
model_type: eg 'model/comment'
model_one_id: eg: '1'
model_one_type: eg 'model/order'
in above relationship we can saving the data from comment to order and order to comment like many to manay.
Now the problem is that how to get the both data from one ORM method. like some time we save comment in model type and some time in model typeOne.
i want to get the data from both models in one go.
public function morphicable(): MorphMany
{
return $this->morphMany(morphicable::class, 'model');
}
Hi I have a table in my database which contains a column with integer values which are actually the primary key of another tabel
Table 1: Details
column : subjects
value : 12,10,1,50,89,88
And another table is subject from where I should fetch the result. I want to know if I can fetch them using my model instead of repeating my code in controller everytime I need to fetch them.
I know you can define relations using
$this->belongsTo()
Or hasMany() depending on circumstances. I want to see If I can use this using scope on Model.
The final result I am looking for is json data returned from table Subject
I would recommend using a polymorphic relationship for this rather than the way you are comma delimiting in a single database table field.
You will have a new record for each association which may seem bad to you at first but it really is worthwhile, work with Eloquent so you don't need to add custom logic to explode those id's and associate manually.
students
id - integer
name - string
subjects
id - integer
name - string
subjectable_id - integer
subjectable_type - string
Then in your models something like this
class Subject extends Model
{
/**
* Get all of the owning subjectable models.
*/
public function subjectable()
{
return $this->morphTo();
}
}
class Student extends Model
{
/**
* Get all of the post's comments.
*/
public function subjects()
{
return $this->morphMany('App\Subject', 'subjectable');
}
}
You can then attach subjects to many different models the same way I demonstrated it attached to Students here.
Edit: If you would like to keep with your same interpretation of how this data is used, you could potentially do this in the Model but it's difficult to say without seeing the logic you are trying not to repeat.
I have 3 tables namely A, B and C.
All 3 of them need to make use of a notes table(i.e. A has many notes and a note belongs to A. The same follows for remaining 2 tables).
So I created 3 more tables: A_note, B_note and C_note(as mentioned here: multiple tables need one to many relationship).
Is there a way to do CRUD operations on these tables(A_note, B_note and C_note) similar to the way we handle pivot table in many-to-many relationship?
Please suggest a way forward.
You should be using polymorphic relationships for this. It allows multiple models to make use of a single table.
Have a look at the documentation here
In your particular case, each of your tables would reference a noteable_id column and a noteable_type.
The noteable_id will contain the id of the (A/B/C) model.
The noteable_type will contain the string name of the model (A/B/C).
The (A/B/C) models will now get a new attribute:
/**
* (A/B/C) Model(s)
*/
public function notes()
{
return $this->morphMany('App\Notes', 'noteable');
}
And the note model will initiate it's polymorphic properties against the attribute name used to identify your polymorphic ids and types:
/**
* Note Model
*/
public function noteable()
{
return $this->morphTo();
}
Now you can simply call ->noteable on the (A/B/C) models, and they all share 1 table without the need of another pivot table for each table.
I'm trying to create a polymorphic relationship with multiple pivot tables. I have a table of requirements that can be assigned to accounts, roles, trips, and countries. This needs to be a many to many relationship because the same requirement could apply to multiple countries and/or trips and/or accounts etc.
I then need a table listing outstanding requirements for the user. For example: if a user has a certain account and there are requirements related to that account, then those requirements would be added to the user's list of requirements.
One solution I have is to first assign the requirements to the accounts, roles, trips, and countries using Pivot tables in a Many to Many relationship. Then using a polymorphic relationship I would connect the user to whichever pivot tables relate.
But I don't know how to do this or if it is even possible?
Here are my tables:
user_requirements
- id
- user_id
- requireable_id
- requireable_type
account_requirement
- id
- account_id
- requirement_id
role_requirement
- id
- role_id
- requirement_id
trip_requirement
- id
- account_id
- requirement_id
country_requirement
- id
- account_id
- requirement_id
Laravel 4.1 now has support for polymorphic many to many relationships.
Example below shows how I have implemented sharing Photos with both Products and Posts.
DB Schema
photos
id integer
filename string
alt string
photoable
id integer
photoable_id integer
photoable_type string
Models
Photo Model
class Photo extends Eloquent
{
public function products(){
return $this->morphedByMany('Product', 'photoable');
}
public function posts(){
return $this->morphedByMany('Post', 'photoable');
}
}
Product Model
class Product extends Eloquent
{
public function photos(){
return $this->morphToMany('Photo', 'photoable');
}
}
Post Model
class Post extends Eloquent
{
public function photos(){
return $this->morphToMany('Photo', 'photoable');
}
}
With the above, I can access all photos which are attached to a product as follows:
$product = Product::find($id);
$productPhotos = $product->photos()->all();
I can also iterate over to display all photos as any collection of models.
foreach ($productPhotos as $photo)
{
// Do stuff with $photo
}
The above can be replicated almost exactly to your requirements.
create a requirements table
create a requireable table
In Requirement model, declare all morphedByMany relationships
In Country, Trip, Role etc. declare morphToMany relationships
nb - I've typed this out freehand in S/O with no code editor, so there will probably be a typo, error or two - but concept remains the same.
A polymorphic relation in Laravel 4 is intended for single MODEL associations, therefore you cannot achieve what you are trying to build with this method. This is due to the fact that a pivot table doesn't represent a Model.