New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[10.x] Added many-to-many relation trough set collumn #48613
base: 10.x
Are you sure you want to change the base?
Conversation
[Illuminate\Database\Relations]
|
After further thought it should be something like |
Made `$localKey` attribute required in `belongsToManySet`
|
I'm not sure how it'll go. I personally don't see this type of database structure in the wild, but who knows? Anyway, this looks like a new definition of relation rather than extension of existing Group::first()
->users()
->createMany([
// ...
])
|
I agree. I'm currently rewriting the relation extending the relation class directly. It currently does not work both ways (when the set collumn is the foreign collumn), so that is also a problem that needs to be solved. |
Added compatibility for reverse relation (with set in foreign collumn)
|
The |
|
Correct me if I am wrong, but wouldn't this relation only work when on a MYSQL connection because |
|
Thanks for your message @AndrewMast
This is true, and something I am working on at the moment. I'm looking to extend laravel with a custom I'll try to make it work, but if it doesn't, it would be inpractical adding it in laravel itself, so i'll just publish it as a package as you suggested. |
Added whereInSet() to laravel query builder
|
I added a new whereInSet() function to the Laravel builder, so it uses the like operator instead of the MySQL-only FIND_IN_SET function. It should work now with all other supported Laravel database engines. I'm still figuring out if there are things that I could have made more efficient, and there is also some logic that needs to be added, for example, adding and removing items from a set. However, I would appreciate any feedback on the quality or usefulness of the current revision of my code. Newly added whereInSet() logic: /**
* Add a "where in set" clause to the query.
*
* @param string $column
* @param mixed|array|null $values
* @param string $boolean
* @param bool $not
* @return $this
*/
public function whereInSet($column, $values = null, $boolean = 'and', $not = false)
{
$type = $not ? 'not like' : 'like';
$groupBoolean = $not ? 'and' : 'or'; // Boolean between the wheres added next
$wheres = [];
foreach (Arr::wrap($values) as $value) {
$wheres[] = [$column, $not ? '!=' : '=', $value, $groupBoolean]; // Value is exact match
$wheres[] = [$column, $type, $value.',%', $groupBoolean]; // Value is first in set
$wheres[] = [$column, $type, '%,'.$value.',%', $groupBoolean]; // Value is in middle of set
$wheres[] = [$column, $type, $value.',%', $groupBoolean]; // Value is last in set
}
return $this->addArrayOfWheres($wheres, $boolean); // Add all wheres to query
}Example use of the User::whereInSet('groups', 1)->get();Raw SQL query in this example: SELECT *
FROM `users`
WHERE (
`groups` = 1
OR `groups` LIKE '1,%'
OR `groups` LIKE '%,1,%'
OR `groups` LIKE '%,1'
); |


Note: This is my first contribution to the laravel framework
I recently worked on a project, where I came across a many-to-many relation with the keys in a set collumn. I couldn't find any 'good' solution to add the relation so I thought, why not add it, since they can be usefull in my opinion. Please note that i'm not experienced in modifying the laravel framework code, since this is my first pr, so any feedback is dearly appreciated.
Summary:
The
hasManyInSetbelongsToManySetrelation allows you to define a many-to-many relation between two tables, using a set collumn, so without having to use a pivot table. While a pivot table is recommended, it is still usefull to use the many-to-many relation in this form.Situation:
Users:
Groups:
Example:
You can setup the relation for the user in this example in the model with
belongsToManySet().You can call the relation just like any other relation in Laravel.