How many polymorphic keys




















Many-to-many polymorphic relations are slightly more complicated than "morph one" and "morph many" relationships. For example, a Post model and Video model could share a polymorphic relation to a Tag model. Using a many-to-many polymorphic relation in this situation would allow your application to have a single table of unique tags that may be associated with posts or videos. Next, we're ready to define the relationships on the models. The Post and Video models will both contain a tags method that calls the morphToMany method provided by the base Eloquent model class.

The morphToMany method accepts the name of the related model as well as the "relationship name". Based on the name we assigned to our intermediate table name and the keys it contains, we will refer to the relationship as "taggable":. Next, on the Tag model, you should define a method for each of its possible parent models.

So, in this example, we will define a posts method and a videos method. Both of these methods should return the result of the morphedByMany method. The morphedByMany method accepts the name of the related model as well as the "relationship name". For example, to access all of the tags for a post, you may use the tags dynamic relationship property:. You may retrieve the parent of a polymorphic relation from the polymorphic child model by accessing the name of the method that performs the call to morphedByMany.

In this case, that is the posts or videos methods on the Tag model:. By default, Laravel will use the fully qualified class name to store the "type" of the related model. However, you may wish to decouple these values from your application's internal structure. For example, instead of using the model names as the "type", we may use simple strings such as post and video. By doing so, the polymorphic "type" column values in our database will remain valid even if the models are renamed:.

You may determine the morph alias of a given model at runtime using the model's getMorphClass method. Conversely, you may determine the fully-qualified class name associated with a morph alias using the Relation::getMorphedModel method:.

You may use the resolveRelationUsing method to define relations between Eloquent models at runtime. While not typically recommended for normal application development, this may occasionally be useful when developing Laravel packages.

The resolveRelationUsing method accepts the desired relationship name as its first argument. The second argument passed to the method should be a closure that accepts the model instance and returns a valid Eloquent relationship definition.

Typically, you should configure dynamic relationships within the boot method of a service provider :. Since all Eloquent relationships are defined via methods, you may call those methods to obtain an instance of the relationship without actually executing a query to load the related models. In addition, all types of Eloquent relationships also serve as query builders , allowing you to continue to chain constraints onto the relationship query before finally executing the SQL query against your database.

For example, imagine a blog application in which a User model has many associated Post models:. You may query the posts relationship and add additional constraints to the relationship like so:. You are able to use any of the Laravel query builder's methods on the relationship, so be sure to explore the query builder documentation to learn about all of the methods that are available to you.

As demonstrated in the example above, you are free to add additional constraints to relationships when querying them. However, use caution when chaining orWhere clauses onto a relationship, as the orWhere clauses will be logically grouped at the same level as the relationship constraint:. The example above will generate the following SQL. As you can see, the or clause instructs the query to return any user with greater than votes.

The query is no longer constrained to a specific user:. In most situations, you should use logical groups to group the conditional checks between parentheses:. The example above will produce the following SQL. Note that the logical grouping has properly grouped the constraints and the query remains constrained to a specific user:.

If you do not need to add additional constraints to an Eloquent relationship query, you may access the relationship as if it were a property. For example, continuing to use our User and Post example models, we may access all of a user's posts like so:.

Dynamic relationship properties perform "lazy loading", meaning they will only load their relationship data when you actually access them. Because of this, developers often use eager loading to pre-load relationships they know will be accessed after loading the model.

Eager loading provides a significant reduction in SQL queries that must be executed to load a model's relations. When retrieving model records, you may wish to limit your results based on the existence of a relationship.

For example, imagine you want to retrieve all blog posts that have at least one comment. To do so, you may pass the name of the relationship to the has and orHas methods:.

Nested has statements may be constructed using "dot" notation. For example, you may retrieve all posts that have at least one comment that has at least one image:. If you need even more power, you may use the whereHas and orWhereHas methods to define additional query constraints on your has queries, such as inspecting the content of a comment:.

The relationships must exist within the same database. If you would like to query for a relationship's existence with a single, simple where condition attached to the relationship query, you may find it more convenient to use the whereRelation and whereMorphRelation methods.

For example, we may query for all posts that have unapproved comments:. Of course, like calls to the query builder's where method, you may also specify an operator:. When retrieving model records, you may wish to limit your results based on the absence of a relationship. For example, imagine you want to retrieve all blog posts that don't have any comments. To do so, you may pass the name of the relationship to the doesntHave and orDoesntHave methods:.

If you need even more power, you may use the whereDoesntHave and orWhereDoesntHave methods to add additional query constraints to your doesntHave queries, such as inspecting the content of a comment:. You may use "dot" notation to execute a query against a nested relationship. For example, the following query will retrieve all posts that do not have comments; however, posts that have comments from authors that are not banned will be included in the results:.

To query the existence of "morph to" relationships, you may use the whereHasMorph and whereDoesntHaveMorph methods. These methods accept the name of the relationship as their first argument.

Next, the methods accept the names of the related models that you wish to include in the query. Finally, you may provide a closure which customizes the relationship query:. You may occasionally need to add query constraints based on the "type" of the related polymorphic model.

This argument allows you to inspect the "type" of the query that is being built:. This will instruct Laravel to retrieve all of the possible polymorphic types from the database.

Laravel will execute an additional query in order to perform this operation:. Sometimes you may want to count the number of related models for a given relationship without actually loading the models. To accomplish this, you may use the withCount method. By passing an array to the withCount method, you may add the "counts" for multiple relations as well as add additional constraints to the queries:. You may also alias the relationship count result, allowing multiple counts on the same relationship:.

Using the loadCount method, you may load a relationship count after the parent model has already been retrieved:. If you need to set additional query constraints on the count query, you may pass an array keyed by the relationships you wish to count.

The array values should be closures which receive the query builder instance:. If you're combining withCount with a select statement, ensure that you call withCount after the select method:. If you wish to access the result of the aggregate function using another name, you may specify your own alias:. Sometimes you may need to eager load a relationship after the parent model has already been retrieved. For example, this may be useful if you need to dynamically decide whether to load related models:.

If you need to set additional query constraints on the eager loading query, you may pass a Closure to the load method:. Just like you would query a relationship , October supports defining a relationship using a method or dynamic property approach. For example, perhaps you need to insert a new Comment for a Post model.

October provides convenient methods for adding new models to relationships. Primarily models can be added to a relationship or removed from a relationship. In each case the relationship is associated or disassociated respectively. Notice that we did not access the comments relationship as a dynamic property.

Instead, we called the comments method to obtain an instance of the relationship. Comparatively, the remove method can be used to disassociate a relationship, making it an orphaned record. In the case of many-to-many relations, the record is removed from the relationship's collection instead. In the case of a "belongs to" relationship, you may use the dissociate method, which doesn't require the related model passed to it.

When working with a many-to-many relationship, the add method accepts an array of additional intermediate "pivot" table attributes as its second argument as an array. The second argument of the add method can also specify the session key used by deferred binding when passed as a string. In these cases the pivot data can be provided as the third argument instead. While add and addMany accept a full model instance, you may also use the create method, that accepts a PHP array of attributes, creates a model, and inserts it into the database.

Before using the create method, be sure to review the documentation on attribute mass assignment as the attributes in the PHP array are restricted by the model's "fillable" definition. Relationships can be set directly via their properties in the same way you would access them. Setting a relationship using this approach will overwrite any relationship that existed previously. The model should be saved afterwards like you would with any attribute.

Alternatively you may set the relationship using the primary key, this is useful when working with HTML forms. Similar to deferred binding , relationships defined on non-existent models are deferred in memory until they are saved. Therefore the association is deferred until the post is created by calling the save method.

When working with many-to-many relationships, Models provide a few additional helper methods to make working with related models more convenient. For example, let's imagine a user can have many roles and a role can have many users. To attach a role to a user by inserting a record in the intermediate table that joins the models, use the attach method:. When attaching a relationship to a model, you may also pass an array of additional data to be inserted into the intermediate table:.

Of course, sometimes it may be necessary to remove a role from a user. To remove a many-to-many relationship record, use the detach method. The detach method will remove the appropriate record out of the intermediate table; however, both models will remain in the database:.

You may also use the sync method to construct many-to-many associations. The sync method accepts an array of IDs to place on the intermediate table. Any IDs that are not in the given array will be removed from the intermediate table. So, after this operation is complete, only the IDs in the array will exist in the intermediate table:. When a model belongsTo or belongsToMany another model, such as a Comment which belongs to a Post , it is sometimes helpful to update the parent's timestamp when the child model is updated.

Just add a touches property containing the names of the relationships to the child model:. Deferred bindings allows you to postpone model relationships binding until the master record commits the changes. This is particularly useful if you need to prepare some models such as file uploads and associate them to another model that doesn't exist yet.

You can defer any number of slave models against a master model using a session key. When the master record is saved along with the session key, the relationships to slave records are updated automatically for you.

Deferred bindings are supported in the back-end Form behavior automatically, but you may want to use this feature in other places. The session key is required for deferred bindings. You can think of a session key as of a transaction identifier. You can generate the session key with PHP uniqid function. Note that the form helper generates a hidden field containing the session key automatically. Use the withDeferred method of a relation to load all records, including deferred.

The results will include existing relations as well. It's a good idea to cancel deferred binding and delete the slave objects rather than leaving them as orphans. You can commit bind or unbind all deferred bindings when you save the master model by providing the session key with the second argument of the save method. Note : October CMS automatically destroys deferred bindings that are older than 5 days.

It happens when a backend user logs into the system. Is there any conventions? The id auto-increment ID is not very useful in table taggables. For taggables eloquent, you can disable primary key, timestamps:.

And you may need to consider the column order when you created the composite primary keys. It depends on the use case of the application. See also: Many-to-Many Mapping table. Stack Overflow for Teams — Collaborate and share knowledge with a private group.

Create a free Team What is Teams? Collectives on Stack Overflow. Learn more. How to set primary key when using many-to-many-polymorphic-relations in laravel ORM qloquent?

I very much doubt these methods are going anywhere. We need to migrate this belongsTo relation on the model to a polymorphic morphTo relation. The model refactor is relatively painless This is just switching to Laravel's convention for morph models.

For more information on this, you can checkout the Laravel docs. All going well, doing the above steps will mean we have made the migration successfully, but we don't want to leave it to chance that we have found all the attribute references.

Eloquent will return null when we access attributes that do not exist. To remedy this for our current application, we are going to create an accessor and a mutator to help catch any remaining references. This allows us to gracefully deprecate the attribute. You could always create your own exception if you wanted. If your application is using mass assignment protection, which I would generally advise against I'll let Mohamed explain why , then you also need to take that into account with this migration.

Leaving it there with all the previous steps also taken into account means this will continue to work as expected. Once you have had this in production for as long as you feel is necessary, you can then go back through and remove all the deprecated bits and pieces.



0コメント

  • 1000 / 1000