lighthouse icon indicating copy to clipboard operation
lighthouse copied to clipboard

`@scope` directive should work with parameters / dynamic scopes

Open dlindenkreuz opened this issue 5 years ago • 5 comments

What problem does this feature proposal attempt to solve?

Currently, the @scope directive only supports scopes without parameters. Laravel describes scopes with parameters as "dynamic scopes".

Which possible solutions should be considered?

One possible way would be to pass parameters similar to how validation rules are passed to the @validate directive: @scope(name: "role:admin,manager")

Another way would be to add a second parameter to the @scope directive itself that takes the scope parameters as an array: @scope(name: "role", parameters: ["admin", "manager"])

dlindenkreuz avatar Aug 12 '20 15:08 dlindenkreuz

While I do like the explicit second version, the first version seems nicer when using the scopes argument of other directives such as @all.

# It is clear what the arguments are for
@all(scopes: ["role:admin,manager"])

# Relation between scopes and parameters is obscured
# Also, parameters has to be list of lists to be able to pass arguments to multiple scopes
@all(scopes: ["role"], parameters: [["admin", "manager"]])

spawnia avatar Aug 13 '20 07:08 spawnia

Yeah, the first one blends in way better with the rest

dlindenkreuz avatar Aug 13 '20 11:08 dlindenkreuz

I would be happy to discuss this further in a PR.

spawnia avatar Aug 13 '20 11:08 spawnia

In the mean time, @scope can also be used as an argument directive. I use it to give clients a filter possibility.

For anyone coming across this one and was puzzled about this question as I was: This request is about using dynamic scopes in a serverside dictated scope situation.

henzeb avatar Sep 16 '20 07:09 henzeb

Using spatie tags package and I would like to be able to define a field using withType scope with the parameter hard-coded in on a morphMany relation.

Such as:

## noinspection GraphQLUnresolvedReference,GraphQLMissingType
extend type MyThing {
    "My Tags"
    tags: [Tag!]! @morphMany(scopes: ["withType:TagTypeHere"])

    "Or per tag type"
    aTags: [Tag!]! @morphMany(scopes: ["withType:a"])
    bTags: [Tag!]! @morphMany(scopes: ["withType:b"])
}

This would give peace of mind that the relations coming back are of the expected type. It would also facilitate having multiple types of tags on the same model returned back as different field names.

Just to clarify, querying with the `@scope(name: "containing") works fine as in my searchTags query below, but being able to use the dynamic scope withType in the morphMany relation would be great for peace of mind.

The scope withType is already defined in their Tag model but I can't seem to use this with scopes.

    public function scopeWithType(Builder $query, string $type = null): Builder
    {
        if (is_null($type)) {
            return $query;
        }

        return $query->where('type', $type)->ordered();
    }

Querying works great.

# noinspection GraphQLUnresolvedReference,GraphQLMissingType
type Tag @model(class: "\\Spatie\\Tags\\Tag") {
    "The tag id"
    id: ID!
    "The tag name in English"
    name: String!
    "The type of the Tag"
    type: TagType!
    "The display order"
    order_column: Int
    created_at: DateTime!
    updated_at: DateTime!
}

# noinspection GraphQLUnresolvedReference,GraphQLMissingType
enum TagType {
    NONE @enum(value: "")
    A @enum(value: "a")
    B @enum(value: "b")
}

# noinspection GraphQLUnresolvedReference,GraphQLMissingType
extend type Query {
    "Search for a tag"
    tags(
        "Filters by name. Accepts SQL LIKE wildcards `%` and `_`."
        search: String! @scope(name: "containing") @trim,
        "The type of tag to search for."
        type: TagType @scope(name: "withType")
    ): [Tag!]! @paginate(defaultCount: 5)
}

Alternatively, maybe I'm thinking about it the wrong way and TagType can be added as a filter mapped with @scope with a default value like below.

tags(type: TagType! = A @scope(name: "withType")): [Tag!]! @morphMany

This seems to work as I can see the type added in my query in Telescope console.

LiamKarlMitchell avatar Aug 21 '23 11:08 LiamKarlMitchell