Home > Net >  How can I make this code easy . i use this query() function for many section
How can I make this code easy . i use this query() function for many section

Time:04-21

** How can I make this code easy . i use this query() function for many section i want to get event by filter. my filter based on tags and category(both are in pivot table) **

public function index(Request $request)
{
    $customQuery = Event::where('status', '1');
    if ($request->vehical_type) { //vehical filter
        $customQuery->where('vehical_type', '=', $request->vehical_type);
    }
    if ($request->tag) { //tag filter
        $id = $request->tag;
        $customQuery->whereHas('tags', function (Builder $query) use ($id) {
            $query->where('tag_id', $id);
        });
    }
    if ($request->category) { //category filter
        $id = $request->category;
        $customQuery->whereHas('categories', function (Builder $query) use ($id) {
            $query->where('category_id', $id);
        });
    }
    $events = $customQuery->get(); //get event according to filters
    $tags = Tag::whereHas('events', function (Builder $query) { //get all tags of events
        $query->where('event_id', '>', 0);
    })->get();
    $categories = Category::whereHas('events', function (Builder $query) { //get all categories of events
        $query->where('event_id', '>', 0);
    })->get();
    return view('frontend.event.index', compact('events', 'tags', 'categories'));
}

CodePudding user response:

You could use when for conditionals in the query and short hand closures with fn to put them in a single line. whereRelation instead of whereHas could make those queries a bit shorter too.

public function index(Request $request)
{
    $events = Event::query()
        ->where('status', '1')
        ->when(
            $request->vehical_type,
            fn($query) => $query->where('vehical_type', $request->vehical_type)
        )
        ->when(
            $request->tag,
            fn($query) => $query->whereRelation('tags', 'tag_id', $request->tag)
            // or fn($query) => $query->whereHas('tags', fn($tags) => $tags->where('tag_id', $request->tag))
        )
        ->when(
            $request->category,
            fn($query) => $query->whereRelation('categories', 'category_id', $request->category)
            // or fn($query) => $query->whereHas('categories', fn($category) => $category->where('category_id', $request->category))
        )
        ->get();

    $tags = Tag::query()
        ->whereRelation('events', 'event_id', '>', 0)
        // or ->whereHas('events', fn($events) => $events->where('event_id', '>', 0))
        ->get();

    $categories = Category::query()
        ->whereRelation('events', 'event_id', '>', 0)
        // or ->whereHas('events', fn($events) => $events->where('event_id', '>', 0))
        ->get();

    return view('frontend.event.index', compact('events', 'tags', 'categories'));
}

You could also maybe use a query scope to put the search in the Event model.

# Event.php
public function scopeSearch(Builder $query, array $filter = [])
{
    return $query
        ->when(
            array_key_exists('vehicle_type', $filter),
            fn($query) => $query->where('vehical_type', $filter['vehicle_type'])
        )
        ->when(
            array_key_exists('tag', $filter),
            fn($query) => $query->whereRelation('tags', 'tag_id', $filter['tag'])
            // or fn($query) => $query->whereHas('tags', fn($tags) => $tags->where('tag_id', $filter['tag']))
        )
        ->when(
            array_key_exists('category', $filter),
            fn($query) => $query->whereRelation('categories', 'category_id', $filter['category'])
            // or fn($query) => $query->whereHas('categories', fn($category) => $category->where('category_id', $filter['category']))
        );
}
public function index(Request $request)
{
    $filter = [
        'vehicle_type' => $request->vehicle_type,
        'tag' => $request->tag,
        'category' => $request->category,
    ];

    $events = Event::query()
        ->where('status', '1')
        ->search($filter)
        ->get();

    $tags = Tag::query()
        ->whereHas('events', fn($events) => $events->where('event_id', '>', 0))
        ->get();

    $categories = Category::query()
        ->whereHas('events', fn($events) => $events->where('event_id', '>', 0))
        ->get();

    return view('frontend.event.index', compact('events', 'tags', 'categories'));
}

CodePudding user response:

You can use whereRelation for getting instead of using whereHas.

$customQuery->whereRelation('tags', 'tag_id', $id)

Using this structure you can shortan your code and optimize.

there is other relationship query method introduced in newer version check here

CodePudding user response:

    // Get event according to filters
    $events = Event::where('status', '1')
        ->when($request->get('vehicle_type'), function ($query, $vehicleType) {
            $query->where('vehical_type', '=', $vehicleType);
        })
        ->when($request->get('tag'), function ($query, $tagId) {
            $query->whereHas('tags', function ($query) use ($tagId) {
                $query->where('tag_id', $tagId);
            });
        })
        ->when($request->get('category'), function ($query, $categoryId) {
            $query->whereHas('categories', function ($query) use ($categoryId) {
                $query->where('category_id', $categoryId);
            });
        })
        ->get();

You can use the when method for these types of conditions. You can view the documentation here.

  • Related