How to elegantly use a remote one-to-many like association on a many-to-many in Laravel - laravel

For example, there are four models as follows.
class User extends Authenticatable
{
public function orders(): MorphMany
{
return $this->morphMany(Order::class, 'orderable');
}
}
class Partner extends Model implements Authenticatable
{
public function orders(): MorphMany
{
return $this->morphMany(Order::class, 'orderable');
}
}
class Order extends Model
{
public function orderable(): MorphTo
{
return $this->morphTo();
}
public function projects(): BelongsToMany
{
return $this->belongsToMany(Project::class)->withPivot('amount', 'price');
}
}
class Project extends Model
{
public function orders(): BelongsToMany
{
return $this->belongsToMany(Order::class)->withPivot('amount', 'price');
}
}
User、Partner and Order are one to many polymorphic relations。
Order and Project are many to many relations。
How to elegantly get all projects enrolled by a given user?
Thanks!

Related

Laravel: Nested relationship method

I have the following models:
users
id
name
organisation_members
id
organisation_id (FK to organisations)
user_id (FK to users)
unqiue(organisation_id, user_id)
organisations
id
name
A user can be a member to many organisations.
My models are written as follows
class User extends Model {
public function organisationMembers(): HasMany
{
return $this->hasMany(OrganisationMember::class);
}
public function organisations()
{
// TODO: how do I do this one
}
}
class OrganisationMember extends Model {
public function organisation(): BelongsTo
{
return $this->belongsTo(Organisation::class);
}
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
}
class Organisation extends Model {
public function organisationMembers(): HasMany
{
return $this->hasMany(organisationMember::class);
}
}
How can I write a relationship method in the User model for organisations?
Thanks to #matiaslauriti comment the answer is:
class User extends Model {
public function organisationMembers(): HasMany
{
return $this->hasMany(OrganisationMember::class);
}
public function organisations()
{
return $this->belongsToMany(Organisation::class, 'organisation_members');
}
}

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

Bind Laravel table to other database connection

I am finding some difficulties to bind one relationship table to my second database.
In "db_main" I have tables, with the basic details about each object and than I have other tables: "db_site1", "db_site2" etc, in which tables I save detailed information about the same objects.
Everything is working find with that schema, except one situation in that I have relationship table (bookmaker_games), which must be only on "db_main". The table save the relations between bookmakers and games.
On my website1 I want to list the games of a bookmaker with the following models:
class Bookmaker extends Model {
public function games() {
// here the database is "db_site1"
return $this->belongsToMany('App\Models\Game', 'bookmaker_games', 'bookmaker_id', 'game_id');
}
}
class Game extends Model {
public function bookmakers() {
// here the database is "db_site1"
return $this->belongsToMany('App\Models\Bookmaker', 'bookmaker_games', 'game_id', 'bookmaker_id');
}
}
class BookmakerGame extends Model {
protected $connection = 'db_main';
}
When I try to return all games, it is thinking that "bookmaker_games"-table is on database "db_site1", which is wrong.
What is the best way to tell that relationship to look at the correct database ?
Declare BookmakerGame as a subclass of Illuminate\Database\Eloquent\Relations\Pivot
Then define the relationships to use it.
Prefixing the connection name
//...
use Illuminate\Database\Eloquent\Relations\Pivot;
class Bookmaker extends Model {
public function games() {
// here the database is "db_site1"
return $this->belongsToMany(
'App\Models\Game', 'db_main.bookmaker_games', 'bookmaker_id', 'game_id')
->using('App\Models\BookmakerGame');
}
}
class Game extends Model {
public function bookmakers() {
// here the database is "db_site1"
return $this->belongsToMany(
'App\Models\Bookmaker', 'db_main.bookmaker_games', 'game_id', 'bookmaker_id')
->using('App\Models\BookmakerGame');
}
}
class BookmakerGame extends Pivot {
protected $connection = 'db_main';
}
Using the class path to the pivot
use Illuminate\Database\Eloquent\Relations\Pivot;
class Bookmaker extends Model {
public function games() {
// here the database is "db_site1"
return $this->belongsToMany(
'App\Models\Game', 'App\Models\BookmakerGame', 'bookmaker_id', 'game_id');
}
}
class Game extends Model {
public function bookmakers() {
// here the database is "db_site1"
return $this->belongsToMany(
'App\Models\Bookmaker', 'App\Models\BookmakerGame', 'game_id', 'bookmaker_id');
}
}
class BookmakerGame extends Pivot {
protected $connection = 'db_main';
protected $table = 'bookmaker_games';
}

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;
}

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