I couldn't get related models in many-to-many polymorphic relation saved into database.
$photo = Photo::find(1);
$photo->articles()->attach(2);
something like this wouldn't work and gives
error: Call to undefined method
Illuminate\Database\Query\Builder::articles()'
How to do it the right way?
Models
class Tag extends Eloquent
{
public function articles()
{
return $this->morphedByMany('Article', 'taggable');
}
public function photos()
{
return $this->morphedByMany('Photo', 'taggable');
}
}
class Article extends Eloquent
{
public function tags()
{
return $this->morphToMany('Tag', 'taggable');
}
}
class Photo extends Eloquent
{
public function tags()
{
return $this->morphToMany('Tag', 'taggable');
}
}
Finally got it working... Basically it's polymorphism + many to many relationship combined. I thought it don't require tags table. Taggables table acts as pivot table and tags is the table which contains Tag objects that connect models based on pivot table (taggables table)
Morphing does not Support Many To Many, it is actually a one to one association, it is used to create relations between different Models, so for example if you have Tag Model, the tag model could relate to many different occasions, it could relate to Page Model, to Post Model, to Product Model etc, what it actually achieves is that it allows you to relate to that other model without explicity defining the related model in the DB level, for instance a Tag model could be associated with a Post Model, but then you would need to define in the db, a post_id foreign key, with Polymorphic relations you can relate to that Post Model, without defining the model on the DB level as a specific field:
Polymorphic relations allow a model to belong to more than one other model, on a single association
And in Django Documentation you can clearly see how this association works:
staff
id - integer
name - string
orders
id - integer
price - integer
photos
id - integer
path - string
imageable_id - integer
imageable_type - string
The association from above is: 1 Photo relates to 1 Other Model, but with a different concrete implementation* thus a photo can belong to Staff, or it can belong to an order.
Related
I have a problem creating a "Double" n:m relation in Laravel.
First I have two tables called locations and services. These tables have a n:m relation and a table called location_service. The table has an incremental id and an id of each table.
In the Models I have the following Code:
class Service extends Model
{
public function locations(){
return $this->belongsToMany('app\Location','location_service','service_id','location_id');
}
}
class Location extends Model
{
public function services(){
return $this->belongsToMany('app\Service','location_service','location_id','service_id');
}
}
In addition, I created a table called tags. This table tag can be linked to several location_service and several location_service can be linked to different tags. I created a table called location_service_tag with an incremental id, the id of the location_service and the id of the tag. But how should I do the model? The point is, that there is no Model like app\Location_Service.
I've got a Company model in which I would like to define two relationships with the User model:
public function users(){
return $this->hasMany('App\User');
}
public function administrator(){
return $this->hasOne('App\User', 'superuserid');
}
I have a superuserid field in my companies table in the database, which is a foreign key to the id of the users table.
I just want to know if this is at all a good strategy or even possible?
Yes, it is a good strategy and it is possible.
In your model you can define as much relations as your model needs. And those relations can be of different types (hasOne, hasMany, belongsTo, etc).
In your case, since the company has multiple users and belongs to a super user, we have two different relations, so, obviously, we need to create two methods in the model to represent these two relations.
Another example: the relation between you and your father. Let's say that there is this implementation of a User model:
class User extends Model
{
public function children()
{
return $this->hasMany(User::class, 'id_parent');
}
public function dad()
{
return $this->belongsTo(User::class, 'id_parent')->where('gender', 'male');
}
}
Here a User can has many children but belongs to just one dad.
I need some help make a music library database.
I have 3 tables albums, artists, roles
I want an artist to have a role for each album.
like :
artist 1 work as Composer for album 1, but also work as arranger on album 2 or work as composer and arranger on album 3
I have tried this
how should database looks? and what type relationship is?
In your current schema, you will not be able to tag the role of the artist on basis of album.
As there is no relation in your tables to define that the entry in artist_role table is for specific album. So, what I would suggest is to create an intermediate table containing the role_id,artist_id and album_id.
To use this intermediate table with laravel's manyToMany relationship, you can define the methods in your models specifying one attribute as pivot attribute.
For, e.g. in Artist Model:
public function Roles(){
return $this->belongsToMany('App\Roles')->withPivot('album_id');
}
public function Albums(){
return $this->belongsToMany('App\Albums')->withPivot('role_id');
}
Define similar methods for other Models also..
Update:
For getting Artist with its role in Album add following method in the Album model:
public function Artists(){
return $this->belongsToMany('App\Artist')->withPivot('role_id');
}
For roles add following method:
public function Roles(){
return $this->belongsToMany('App\Roles')->withPivot('artist_id');
}
I've been working with PHP for years but have never really ventured out of procedural programming except when working with things like IPB and Magento. I'm trying to advance to the next level and get a better understanding of application structures, OOP, and some common PHP frameworks. That being said, I apologize if my question sounds immature or technically incorrect, I'm new to all of this.
Anyway, I was thinking about the structure of a simple forum. Forgetting about categories, tags, users, roles, advanced editors/bbcode, etc for now and just focusing on the topics and posts...
Because a topic is essentially a series of linked posts ordered by their created_at column, is there a necessity for an actual topics table or could one not simply have a parent column in the posts table? Topics would be identified as posts with a parent equal to their own id, null or 0; something that would otherwise be unused.
If that were the db schema, how would it be laid out in the code, and if relevant, Laravel? Could you still create a Topic model? What would be the pros and cons to having two models working from a single table?
Lastly, how would you approach it if you were creating it? Would you use two tables? A pivot table? Something else? Please explain why you would implement it that way.
For the database design, self referencing tables are a valid design pattern and useful in cases of nested hierarchies such as Categories that can contain sub-categories that can also contain sub-categories ect ect... In this case sub-categories are categories that have a parent but there is no other distinction between them.
It's up to you to decide if a Topic and Post is an identical entity with a parent-child relationship. Personally the way I define the objects I don't feel they are.
The topic-post relationship you're describing is probably more of a One to Many relationship with the topic being the owner or maybe even a Many to Many relationship. This depends on the answer to, "can your topic have many posts? Can your posts be part of many topics?"
If you answered yes and no, then it is a One to Many with topics being the parent aka owner in the relationship.
If you answered yes and yes, then you have a Many to Many relationship. In SQL these are represented by a table with two columns that reference id's from two tables.
If you answered no and yes, then you have a One to Many with posts being the parent aka owner in the relationship.
In laravel, depending on the relationship, your models would include a method that looks like this:
One to Many:
class Topic extends Eloquent
{
public function posts()
{
return $this->hasMany('Post');
}
}
Laravel One-to-Many Relationships
Many to Many:
In laravel the term "pivot table" refers to the table with references to the other objects.
class Post extends Eloquent
{
public function topics()
{
return $this->belongsToMany('Topic');
}
}
class Topic extends Eloquent
{
public function posts()
{
return $this->belongsToMany('Post');
}
}
Laravel Many-to-Many
Self referencing model:
For a self referencing parent child relationship like I explained before you could create something like this, as you can see it's just a one-to-many and the many-to-one in the same model.
class Category extends Eloquent
{
public function parent()
{
return $this->belongsTo('Category', 'parent_id');
}
public function children()
{
return $this->hasMany('Category', 'parent_id');
}
}
There is also the Polymorphic Relation.
This is useful when you have the same entity with just a different type. For example in this table you can have an insurance policy for an employee and a manager. The personType column in the insurancePolicies table defines who the insurance policy belongs to.
Image from codecommit.com
Our laravel models in this case would look like:
class InsurancePolicy extends Eloquent
{
public function insurable()
{
return $this->morphTo();
}
}
class Manager extends Eloquent
{
public function insurance()
{
return $this->morphMany('InsurancePolicy', 'person');
}
}
class Employee extends Eloquent
{
public function insurance()
{
return $this->morphMany('InsurancePolicy', 'person');
}
}
Most everything of what I've explained can also be found in the laravel docs
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.