In laravel 7 app I app/Forum.php model with method:
public function forumThreads()
{
return $this->hasMany('App\ForumThread', 'forum_id', 'id');
}
app/ForumThread.php has field forum_id and:
public function forum()
{
return $this->belongsTo('App\Forum', 'id');
}
public function forumPosts()
{
return $this->hasMany('App\ForumPost');
}
and in app/ForumPost.php there are field forum_thread_id and:
public function forumThread()
{
return $this->belongsTo('App\ForumThread'/*, 'user_id'*/);
}
can I in app/Forum.php make method referring post:
public function forumPosts()
{
return $this->hasMany('App\ForumPost');
}
and if yes, how?
Thanks!
Though your eloquent looks confusing, but i will say guess what might need is using the "has many through" and "has one through" relationship.
Related
How could I set relationships to use just one table (model_types) in Laravel to store types for cars and bikes?
Car model
public function carTypes()
{
return $this->hasMany(CarType::class);
}
CarType model (inverse relationship):
public function car()
{
return $this->belongsTo(Car::class);
}
Bike model
public function bikeTypes()
{
return $this->hasMany(BikeType::class);
}
BikeType model (inverse relationship):
public function bike()
{
return $this->belongsTo(Bike::class);
}
There are 2 options I can think of to solve this problem, the first being a simple table using a type column and the other is using polymorphic relations which is a little overkill.
The first option is to have a type column on your model_types table which you could use to determine the type and adding constants in your ModelType class like this:
const TYPE_CAR = 1;
const TYPE_BIKE = 2;
Then you can easily access the data like so, so from the Car model it's
public function modelType()
{
return $this->belongsTo(ModelType::class)->where('type', ModelType::TYPE_CAR);
}
If you wanted to access it from the model_types table it would look like this:
public function cars()
{
return $this->hasMany(Car::class)
}
public function bikes()
{
return $this->hasMany(Bike::class)
}
You have it reversed.
A car can belong to one car type, but one car type can apply to many cars.
The same goes for bikes.
You don't need a polymorphic relationship.
Car model
public function carType()
{
return $this->belongsTo(ModelType::class);
}
Bike model
public function bikeType()
{
return $this->belongsTo(ModelType::class);
}
ModelType model
public function cars()
{
return $this->hasMany(Car::class);
}
public function bikes()
{
return $this->hasMany(Bike::class);
}
Not sure about inverse relationship, but in your Car model you should use
public function carTypes()
{
return $this->hasMany(ModelType::class, 'foreign_key', 'local_key');
}
Car Model:
public function carTypes() {
return $this->hasMany(ModelType::class);
}
Bike Model:
public function bikeTypes() {
return $this->hasMany(ModelType::class);
}
ModelType Model:
public function car() {
return $this->belongsTo(Car::class, 'modeltype_car_id');
}
public function bike() {
return $this->belongsTo(Bike::class, 'modeltype_bike_id');
}
Models and relations
class Publisher extends Model
{
use HasRelationships;
public function collections(): BelongsToMany
{
return $this->belongsToMany(Collection::class)
->orderBy('title')
->using(CollectionPublisher::class);
}
public function series(): HasManyDeep
{
return $this->hasManyDeepFromRelations($this->collections(), (new Collection())->series());
}
}
class Collection extends Model
{
use HasRelationships, Translatable;
public function editions(): HasMany
{
return $this->hasMany(Edition::class);
}
public function series(): HasManyDeep
{
return $this->hasManyDeepFromRelations($this->editions(), (new Edition)->series());
}
}
class Edition extends Model
{
use HasRelationships, LoadsRelationshipsWithoutScopes, Translatable;
public function series(): BelongsTo
{
return $this->belongsTo(Series::class);
}
public function collection(): BelongsTo
{
return $this->belongsTo(Collection::class);
}
}
And of course there is a Series model.
The problem is that the series relation on the Publisher is returning each Series as many times as there is an Edition for that Publisher in the Series
How do I trim it down so each series is only returned once?
A simple groupBy('series.id') does not work due to the full group by limitations, and I'm not sure how to get around this using the has many deep package.
I finally came up with a solution
On the Publisher model:
public function series(): Builder
{
return $this->hasManyDeepFromRelations($this->collections(), (new Collection())->series())
->getQuery()
->select('series.*')
->groupBy('series.id');
}
The getQuery() part (undocumented in Laravel) limits the scope and allows the groupBy() to work
Thanks to Jonas Staudenmeir for the help
I'm having a problem while creating a Forum with Laravel 5.7
I want to have these three models: User, Category, Thread and Post. The problem is that i don't how to define one of my Thread model relationships.
This model has a creator:
public function creator()
{
return $this->belongsTo('App\User');
}
...it has a series of replies:
public function replies()
{
return $this->hasMany('App\Post');
}
...and, finally, participants:
public function participants()
{
return $this->hasManyThrough('App\User', '???')
}
I should get the thread participants through its replies but it don't know if i should put the post class like this:
public function participants()
{
return $this->hasManyThrough('App\User', 'App\Post')
}
...or if this is an special case with some considerations. Any help?
Since posts acts as a pivot table, a BelongsToMany relationship is the better choice here:
public function participants()
{
return $this->belongsToMany('App\User', 'posts');
}
I have a project with main table 'Qsos' and bunch of relations. Now when I try to create advanced search I don't really know how to query all relations at the same time. Qso model has following:
public function band()
{
return $this->belongsTo('Band');
}
public function mode()
{
return $this->belongsTo('Mode');
}
public function prefixes()
{
return $this->belongsToMany('Prefix');
}
public function user()
{
return $this->belongsTo('User');
}
public function customization() {
return $this->hasOne('Customization');
}
Then I have SearchController with following code that has to return collection of all Qsos following required conditions:
$qsos = Qso::withUser($currentUser->id)
->join('prefix_qso','qsos.id','=','prefix_qso.qso_id')
->join('prefixes','prefixes.id','=','prefix_qso.prefix_id')
->where('prefixes.territory','like',$qTerritory)
->withBand($qBand)
->withMode($qMode)
->where('call','like','%'.$input['qCall'].'%')
->orderBy('qsos.id','DESC')
->paginate('20');
And then in view I need to call $qso->prefixes->first() and $qso->prefixes->last() (Qso and Prefix has manyToMany relation) but both return null. What is wrong?
Here is the eloquent code that I found working but taking VERY long time to process:
$qsos = Qso::withUser($currentUser->id)
->with('prefixes')
->withBand($qBand)
->withMode($qMode)
->where('call','like','%'.$input['qCall'].'%')
->whereHas('prefixes', function($q) use ($qTerritory) {
$q->where('territory','like',$qTerritory);
})
->orderBy('qsos.id','DESC')
->paginate('20');
I'm trying to setup some simple favoriting for my app using Laravel/Jenssegers MongoDB
I have two models:
class Item {
public function favorites()
{
return $this->hasMany('App\Models\User', 'favorites');
}
}
class User {
public function favorites()
{
return $this->hasMany('App\Models\Item', 'favorites');
}
}
So an item can have many users and a user can have many items or "favorites".
When I try to run a simple query like:
Item::with('favorites')->get();
The relationship for favorites is there but an empty array.
The favorites table is simple and just has three columns:
_id, item_id, user_id
I've also tried using embedsMany with no luck:
return $this->embedsMany('App\Models\User', 'favorites');
I've also tried every combination of parameters.
return $this->embedsMany('App\Models\User', 'favorites', 'building_id', 'user_id');
return $this->embedsMany('App\Models\User', 'favorites', 'user_id', 'building_id');
return $this->hasMany('App\Models\User', 'favorites', 'building_id', 'user_id');
return $this->hasMany('App\Models\User', 'favorites', 'user_id', 'building_id');
Strange results when using:
return $this->hasMany('App\Models\User', 'favorites', 'building_id', 'user_id');
Only in this situation it returns ALL users, even though favorites has only one record.
Also trying to debug using getQueryLog just gives me an empty array at all times.
print_r(\DB::connection('mongodb')->getQueryLog());
I've done this using mysql and have never had issues. So not really sure where the issues are coming from.
Can you try these instead, I know its the same thing but might do the trick :
use App\User;
use App\Item;
class Item {
public function favorites()
{
return $this->hasMany('User');
}
}
class User {
public function favorites()
{
return $this->hasMany('Item');
}
}
class Favourite {
public function users()
{
return $this->belongsTo('User');
}
public function items()
{
return $this->belongsTo('Item');
}
}
Also add inverse of the above relations like: belongsTo.
and try this query then :
//Just for testing purpose, if raw query returns right result
$items = DB::table('items')
->join('favorites','items.id','=','favorites.id')
->get();