Get all records from another table with pivot - laravel

I have three tables:
comments
id
comment_links
id | comment_id | link_id
links
id
I want to get all Links associated with each Comment. As you can see, CommentLink should act as a pivot table, but I don't know how to set up the relationships to make this work. I think I need to use the hasManyThrough relationship, but I'm not 100% sure.
Here are my current class relationships (they may be wrong):
Comment.php:
class Comment extends Model
{
public function commentLinks()
{
return $this->hasMany('App\CommentLink', 'comment_id', 'id');
}
public function links()
{
// How do I fetch all links here using the pivot table?
}
}
CommentLink.php:
class CommentLink extends Model
{
public function comment()
{
return $this->belongsTo('App\Comment');
}
public function link()
{
return $this->hasOne('App\Link', 'id', 'link_id');
}
}
Link.php:
class Link extends Model
{
public function commentLinks()
{
return $this->belongsToMany('App\CommentLink', 'link_id', 'id');
}
}
What do I need to do here to make this work?

You have the right idea, just using the wrong class names.
class Link extends Model
{
public function comments()
{
return $this->belongsToMany('App\Comment');
}
}
class Comment extends Model
{
public function links()
{
return $this->belongsToMany('App\Link');
}
}
You don't actually need to have a class for your pivot table, but you can if you want.
This is quite a good guide on how to do this.
https://laraveldaily.com/pivot-tables-and-many-to-many-relationships/

Related

One to Many Relationship Over Pivot Table

I have existing data in the database, and I want to create a one-to-many relationship. How can I limit or simulate a one-to-many relationship when I'm using a pivot table?
I want to get the data from the pivot table, so I thought it could be done like this.
class Asset extends Model {
public function publisher() {
return $this->belongsTo(Publisher::class, 'asset_publisher');
}
}
-
class Publisher extends Model {
public function assets() {
return $this->hasMany(Asset::class, 'asset_publisher');
}
}
A possible way to simulate the one-to-many is creating a model for the pivot table "AssetPublisher" so you will now have
class Publisher extends Model {
public function assets() {
return $this->belongsToMany(Asset::class, 'asset_publisher');
}
}
class AssetPublisher extends Model {
public function publisher() {
return $this->belongsTo(Publisher::class);
}
}
class Asset extends Model {
public function assetPublisher() {
return $this->hasOne(AssetPublisher::class)->with('publisher');
}
public function getPublisherAttribute(){
return $this->assetPublisher->publisher;
}
}
You can now call $asset->publisher to give you the Publisher instance and $publisher->assets()->get() to get all assets instances

Laravel Eloquent for hasMany relation cannot find records

I can not find why it does not work.
In my Course model I have defined relation:
class Course extends Model {
public function courseDates() {
return $this->hasMany(CourseDate::class, 'course_id');
}
}
And in my CourseDate model this:
class CourseDate extends Model {
public function course() {
return $this->belongsTo(Course::class);
}
}
When I try to access CourseDates from Course I will always get null, but when I access Course from CourseDate, it works and I see all data:
var_dump(CourseDate::where('id', 1)->first()->course->name); => output: "Course 1"
var_dump(Course::where('id', 1)->first()->courseDate); => output: null
And what's strange when I try it with another course (like ID 2) then it works. The data is absolutely the same in the database. Any Ideas?
You shouldent add class like CourseDate::class instead you should add it like below
class Course extends Model {
public function courseDates() {
return $this->hasMany('App\CourseDate', 'course_id');
}
}
And in your CourseDate model
class CourseDate extends Model {
public function course() {
return $this->belongsTo('App\Course');
}
}
And your relationship method for Course model is courseDates so you should use it like below
var_dump(Course::where('id', 1)->first()->courseDates);
Documentation : https://laravel.com/docs/5.7/eloquent-relationships

Laravel 5.4 table relationship between 3 small tables

I have a recently started learning Laravel 5.4, I am having trouble with my 3 way table relationship, I've looked at a few articles online regarding many to many, but this relationship is just a "hasOne" on both sides.
Could anyone give me a helpful hint as to how to structure my table relationship, here is the PK/FK relationship:
Users table (id)
Listings table (id, user_id)
Insights table (id, listing_id) - one insight row per listing only.
And the models below:
Users Model
class User extends Model
{
public function listing()
{
return $this->belongsTo('App\Listing');
}
}
Listing Model
class Listing extends Model
{
public function insight()
{
return $this->hasOne('App\Insight');
}
}
Insight Model
class Insight extends Model
{
public function listing()
{
return $this->hasOne('App\Listing');
}
}
And what I am trying to achieve is to query the users own listings, with each listings current insights.
Thanks a bunch.
Simon.
User model
class User extends Model
{
public function listing()
{
return $this->hasOne('App\Listing');
}
}
Listing Model
class Listing extends Model
{
public function insight()
{
return $this->hasOne('App\Insight');
}
public function user()
{
return $this->belongsTo('App\User');
}
}
Insight Model
class Insight extends Model
{
public function listing()
{
return $this->belongsTo('App\Listing');
}
}
And if you want query users with Listing and Insight
$users = User::with(['listing', 'listing.insight'])->get();
foreach($users as $user) {
$user->listing->insight;
}
class User extends Model
{
public function listing()
{
return $this->hasMany(Listing::class);
}
}
class Listing extends Model
{
public function insight()
{
return $this->hasOne(Insight::class);
}
public function user()
{
return $this->belongsTo(User::class);
}
}
class Insight extends Model
{
public function listing()
{
return $this->belongsTo(Listing::class);
}
}
$users = User::with('listing.insight')->get();
foreach($users as $user) {
$user->listing->insight;
}

HasManyThrough with polymorphic and many-to-many relations

In my Laravel application I have the following classes:
class Product extends Model
{
public function extended()
{
return $this->morphTo();
}
public function users {
return $this->belongsToMany('App\User', 'products_users', 'product_id');
}
}
class Foo extends Model
{
public function product()
{
return $this->morphOne('App\Product', 'extended');
}
public function bars()
{
return $this->hasMany('App\Bar');
}
}
class Bar extends Model
{
public function product()
{
return $this->morphOne('App\Product', 'extended');
}
public function foo()
{
return $this->belongsTo('App\Foo');
}
}
class User extends Model
{
public function products()
{
return $this->belongsToMany('App\Product', 'products_users', 'user_id');
}
}
I can easily get users of a bar object using Bar::find(1)->product->users and I can also get the bars of a user with User::find(1)->products.
How can I get the users of all bars belonging to a specific foo? That is, Foo::find(1)->users should return all users that have the bars belonging to Foo with id 1. It's basically hasManyThrough with polymorphic and many-to-many relations.
Try something like this:
public function users()
{
$Foo = static::with(['bars', 'bars.products', 'bars.product.users'])->get();
return collect(array_flatten(array_pluck($Foo, 'bars.*.product.users')));
}
This should work for you (code has been tested, but not against the exact same structure as your setup). The first line will return all the users deeply nested through the relationships. The second line will pull out the users, flatten them into an array, then transform the array into a collection.
I created a HasManyThrough relationship for cases like this: Repository on GitHub
After the installation, you can use it like this:
class Foo extends Model {
use \Staudenmeir\EloquentHasManyDeep\HasRelationships;
public function users() {
return $this->hasManyDeep(
User::class,
[Bar::class, Product::class, 'products_users'],
[null, ['extended_type', 'extended_id']]
);
}
}

Laravel Eloquent Relationship Through Another Table

I have the following database tables:
Seasons
id
number
Teams
id
name
Standings
id
season_id
team_id
The question is, how could I get all of the teams in a season through the standings table. At the moment I am getting all of the teams this way:
$teams = [];
$standings = $season->standings;
foreach($standings as $standing){
$teams[] = $standing->team;
}
Is there a way I could do this using Eloquent relationships? I have tried HasManyThrough with no success. These are what my models look like currently:
class Season extends Eloquent{
public function standings(){
return $this->hasMany('Standing');
}
}
class Standing extends Eloquent{
public function team(){
return $this->belongsTo('Team');
}
}
class Team extends Eloquent{
public function standings(){
return $this->belongsToMany('Standing');
}
}
Your relationships look a little off. Here is all the relationships you should need though only the belongsToMany ones are required for this specific scenario of finding all the teams in a season.
class Season extends Eloquent {
public function teams()
{
return $this->belongsToMany('Team', 'Standings');
}
public function standings()
{
return $this->hasMany('Standing');
}
}
class Team extends Eloquent {
public function seasons()
{
return $this->belongsToMany('Season', 'Standings');
}
public function standings()
{
return $this->hasMany('Standing');
}
}
class Standing extends Eloquent {
public function team()
{
return $this->belongsTo('Team');
}
public function season()
{
return $this->belongsTo('Season');
}
}
You would use the belongsToMany relationship rather than a hasManyThrough to query all the teams in a season. That would look something like...
Season::with('teams')->find($season_id);
foreach($season->teams as $team) {
echo $team->name;
}

Resources