orest

orest

Member Since 8 Months Ago

Experience Points
44,790
Total
Experience

210 experience to go until the next level!

In case you were wondering, you earn Laracasts experience when you:

  • Complete a lesson — 100pts
  • Create a forum thread — 50pts
  • Reply to a thread — 10pts
  • Leave a reply that is liked — 50pts
  • Receive a "Best Reply" award — 500pts
Lessons Completed
406
Lessons
Completed
Best Reply Awards
0
Best Reply
Awards
  • start your engines Created with Sketch.

    Start Your Engines

    Earned once you have completed your first Laracasts lesson.

  • first-thousand Created with Sketch.

    First Thousand

    Earned once you have earned your first 1000 experience points.

  • 1-year Created with Sketch.

    One Year Member

    Earned when you have been with Laracasts for 1 year.

  • 2-years Created with Sketch.

    Two Year Member

    Earned when you have been with Laracasts for 2 years.

  • 3-years Created with Sketch.

    Three Year Member

    Earned when you have been with Laracasts for 3 years.

  • 4-years Created with Sketch.

    Four Year Member

    Earned when you have been with Laracasts for 4 years.

  • 5-years Created with Sketch.

    Five Year Member

    Earned when you have been with Laracasts for 5 years.

  • school-in-session Created with Sketch.

    School In Session

    Earned when at least one Laracasts series has been fully completed.

  • welcome-newcomer Created with Sketch.

    Welcome To The Community

    Earned after your first post on the Laracasts forum.

  • full-time-student Created with Sketch.

    Full Time Learner

    Earned once 100 Laracasts lessons have been completed.

  • pay-it-forward Created with Sketch.

    Pay It Forward

    Earned once you receive your first "Best Reply" award on the Laracasts forum.

  • subscriber Created with Sketch.

    Subscriber

    Earned if you are a paying Laracasts subscriber.

  • lifer Created with Sketch.

    Lifer

    Earned if you have a lifetime subscription to Laracasts.

  • evangelist Created with Sketch.

    Laracasts Evangelist

    Earned if you share a link to Laracasts on social media. Please email [email protected] with your username and post URL to be awarded this badge.

  • chatty-cathy Created with Sketch.

    Chatty Cathy

    Earned once you have achieved 500 forum replies.

  • lara-veteran Created with Sketch.

    Laracasts Veteran

    Earned once your experience points passes 100,000.

  • 10k-strong Created with Sketch.

    Ten Thousand Strong

    Earned once your experience points hits 10,000.

  • lara-master Created with Sketch.

    Laracasts Master

    Earned once 1000 Laracasts lessons have been completed.

  • laracasts-tutor Created with Sketch.

    Laracasts Tutor

    Earned once your "Best Reply" award count is 100 or more.

  • laracasts-sensei Created with Sketch.

    Laracasts Sensei

    Earned once your experience points passes 1 million.

  • top-50 Created with Sketch.

    Top 50

    Earned once your experience points ranks in the top 50 of all Laracasts users.

Level 9
44,790 XP
Oct
22
3 days ago
Activity icon

Started a new Conversation Laravel Controller Methods Naming Convention Alternatives

I have a FollowController and i want to

  1. get list of user that a user follows ( following )
  2. get list of users that a user is followed by ( followers )

However i can't do that in the same controller without breaking the naming convention or without introducing if statements in the controller.

I would like to know your opinion on this.

First Approach

Create separate controllers

class FollowersController extends Controller
{
	public function index(User $user)
	{
		return $user->followedBy;
	}

}

class FollowingController extends Controller
{
	public function index(User $user)
	{
		return $user->follows;
	}

}

Second Approach

Break the naming convention and fit both in the same controller

class FollowController extends Controller
{
	public function followedBy(User $user)
	{
		return $user->followedBy;
	}

	public function follows(User $user)
	{
		return $user->follows;
	}

}

Third Approach

Use a flag to decide whether to return either one or both ( in this case 1 extra request is avoided and you serve both in a single request )

class FollowControllerr extends Controller
{
	public function index(User $user)
	{
		if (request()->boolean('follows'))
		{
			return $user->follows;
		}
		elseif (request()->boolean('followedBy'))
		{
			return $user->followedBy;
		}
		return [
			'follows' => $user->follows, 
			'folllowedBy' => $user->followedBy
 ];
	}

}
Oct
13
1 week ago
Activity icon

Replied to Instantiation Of Chained Filters

@bugsysha that cleaner indeed.

initially what i wanted to do is something like

public function index(ThreadFilters $filters)
{
	$filters->apply($someBuilder);
}

So the controller wouldn't have to know anything except for applying the filters.

But unfortunately since i had to chain Filter in some cases i created the FilterManager and then i couldn't use the aforementioned approach.

However, your suggestions is much better than my final approach. so thank you again

Activity icon

Replied to Instantiation Of Chained Filters

@bugsysha no there are no default filters in FilterManager

The FilterManager exists to find the requested filters that are passed from an HTTP request ( the requested filters correspond to methods in Filter classes ) . I then manually chain the required Filter classes depending on where i need the FilterManager and finally i apply the filters using the FilterManager

Activity icon

Replied to Instantiation Of Chained Filters

@bugsysha oh now i understand your question.

Because in some cases i might need to add 2 different Filter classes

for example

$filterManager->addFilter(new ThreadFilters(());
$filterManager->addFilter(new PostFilters());

Then when i call

$filterManager->apply($someBuilder);

I apply the filters from both Filter classes. In addition to that, in some cases these Filter classes have some methods in common that are inherited from another Filter class and in the FilterManager i prevent applying the same filter twice ( which i don't know if it makes much sense since the filters are actually SQL where statements which i guess are not costly )

Activity icon

Replied to Instantiation Of Chained Filters

@bugsysha it's not quite clear to me what do you mean by "why".

In the ThreadController and more specifically in the method index, i know that i need the ThreadFilters, that's why i add the filter ThreadFilters. In other places i might need a different filter. And in some cases i need two different Filter classes

class ThreadController extends Controller
{
	public function index(FilterManager $filterManager)
	{
	$filterManager->addFilter(new ThreadFilters());
	 // here i know that i need the ThreadFilters
	}
}
Activity icon

Replied to Instantiation Of Chained Filters

@bugsysha thanks again! any suggestions for a better approach are appreciated :)

Activity icon

Replied to Instantiation Of Chained Filters

@bugsysha thanks. Isn't an issue that i have to manually

$filterManager->addFilter(new ThreadFilters());

where ThreadFilters i guess is also a dependency that is hidden.

or it is even better to do the following

class ThreadController(FilterManager $filterManager, ThreadFilters $threadFilters)
{
	$filters = $filterManager->addFilter($threadFilters);
	$filters->apply($someBuilder);
}
Activity icon

Started a new Conversation Instantiation Of Chained Filters

I have different Filter classes and each class has a number of filter methods. There is ( so far ) one case where I need to apply filters from 2 classes. What I did is that I created another class named FilterManager which stores a list of all the Filter classes you need and then it iterates over the list and applies the filters.

class ThreadFilters 
{
	protected $builder;
	protected $supportedFilters = ['newThreads'];
	public function newThreads($userId)
	{
		$this->builder->orderBy('created_at', 'DESC');
	}
}
class FilterManager
{
	protected $filters = [];
	
	public function addFilter($filter)
	{
		$this->filters[] = $filter;
	}

	public function apply($builder)
	{
		foreach($this->filters as $filter)
		{
				$filter->builder = $builder;
				foreach($filter->supportedFilters as $filterMethod)
				{	
					$filter->$filterMethod()
				}
				$builder = $filter->builder;
		}
	
	}
}

Now in the controller I can do something like

First Approach

class ThreadController(FilterManager $filterManager)
{
	$filters = $filterManager->addFilter(new ThreadFilter());
	$filters->apply($someBuilder);
}

On the other hand I could use the app function

app(ThreadFilters::class)

and in the service container basically I could do

$this->app->bind(ThreadFilters::class, function($app){
	$filterManager = new FilterManager();
	$filterManager->addFilter(new ThreadFilters());
	return $filterManager;
});

and therefore my controller would look like

Second Approach

class ThreadController()
{
	$filters = app(ThreadFilters::class);
	$filter->apply($someBuilder);
}

My question is which solution is good/acceptable.

In the First Approach the FilterManager dependency is injected and the controller has to add the ThreadFilters

In the Second Approach no dependencies are injected and the controller has to use the service container to hide the specifics and make the controller has less knowledge about the filters.

Oct
12
1 week ago
Activity icon

Replied to Factory That Depends On Request Parameters

@rodrigo.pedra that's a very nice idea, thank you

Activity icon

Replied to Factory That Depends On Request Parameters

@automica hahaha oh no. is just a simple example to illustrate the question

Activity icon

Replied to Factory That Depends On Request Parameters

i have updated the question ( basically is a question on top of the initial question ).

To make sure that i'm not on the wrong way

Activity icon

Started a new Conversation Factory That Depends On Request Parameters

Given that I have a factory class that create fruits based on a request parameter.

Should the client know the exact parameter that needs to be passed to the factory ( First Approach)

Or it is better to pass a generic parameter to the Factory ( in other words hide the specifics from the client ) and let the Factory know which exact parameter it needs to create an object. ( Second Approach )

First Approach

class FruitFactory
{

    public function create($type)
    {
        if($type == 'Apple')
        {
            return new Apple();
        }
    }
}

$fruitFactory = new FruitFactory();
$type = request('type');
$fruit = $fruitFactory->create($type);

Second Approach

class FruitFactory
{

    public function create(Request $request)
    {
	$type = request('type');

        if($type == 'Apple')
        {
            return new Apple();
        }
    }
}

$fruitFactory = new FruitFactory();
$fruit = $fruitFactory->create();

Updated Question

If the FruitFactory is a factory of factories, does it need to know about all the exact parameters that its children factories need to create an object ?

Or maybe in this case the second approach is better ( Just passing the general $request parameter and let the factory find out which parameter it needs to create an object )

class FruitFactory
{

    public function create($type, $color)
    {
        if($type == 'Apple')
        {
		return app(Apple::class)->create($color);
        }
    }
}


class Apple
{
	public function create($color)
        {
		if($color == 'green') 
		{
			return new GreenApple();
		}
	}

}


$fruitFactory = new FruitFactory();
$type = request('type');
$color = request('color');

$fruitFactory->create($type, $color);

Oct
11
2 weeks ago
Activity icon

Replied to Resolve Dependencies In Service Container Vs Resolve Locally

@martinbean so it is not a good idea to store the dependencies inside the ServiceProvider class but instead to create a class ( SpamChecker ) that resolves ( stores the list with all $inspections classes ) the dependencies for Spam

Activity icon

Started a new Conversation Resolve Dependencies In Service Container Vs Resolve Locally

In one of his videos, Jeffrey has the following code

class Spam
{
    protected $inspections = [
        InvalidKeywords::class,
        KeyHeldDown::class,
    ];

    public function detect($body)
    {
        foreach ($this->inspections as $inspection) {
            app($inspection)->detect($body);
        }
        return false;
    }

}

I was wondering if it is better to inject the dependencies using a service provider class whenever the Spam class is needed

class SpamServiceProvider extends ServiceProvider
{

	public function register()
	{
		$this->app->bind(Spam::class, function($app){
			protected $inspections = [ InvalidKeywords::class, KeyHeldDown::class ];
			
			$spam = new Spam($inspections);
			return $spam;

		});
	}
}
class Spam
{
    protected $inspections;
    
    public function __construct( Inspections $inspections)
    {
            $this->inspections = $inspections
     }


    public function detect($body)
    {
        foreach ($this->inspections as $inspection) {
            $this->inspection->detect($body);
        }
        return false;
    }

}

Is it ok to store the dependencies in the SpamServiceProvider class ? considering that the Spam class is aware of its dependencies since are being injected via the constructor.

Oct
08
2 weeks ago
Activity icon

Replied to Simplify Nested If Statements

@martinbean is not only the type that determines the strategy that needs to be used.

  • The query parameter q determines whether Algolia is going to be used or the Database
  • The query parameter type determines whether the user is searching for Threads or ProfilePosts or All kind of posts
  • The query parameter only_title in combination with the type and the q can lead to a different strategy again.

That's why I nested strategies within strategies.

  • First I create either an AlgoliaSearch instance or a DatabaseSearch instance ( depending on the parameter q)

  • Then based on the type and the only_title I create another strategy which is a branch of either AlgoliaSearch or DatabaseSearch

So to give an example with the possible combinations

Search -> AlgoliaSearch -> SearchThreads

Search -> DatabaseSearch -> SearchThreads

Where the SearchThreads strategy is different for AlgoliaSearch and DatabaseSearch

The way I have it now I can still update only the factories and not the controller.

  • So If I have a new search engine (for example ElasticSearch ) I can add a new if statement in the SearchFactory class

  • If I have a new type I can add a new if statement in AlgoliaSearchFactory

Oct
07
2 weeks ago
Activity icon

Replied to Simplify Nested If Statements

class Search 
{
	 public function __construct(){
             $this->strategy = app(SearchFactory::class)->create();
         }

        public function getResults()
        {
             return $this->strategy->search();
         }
}
class SearchFactory
{
    public function create()
    {
        if (request()->missing('q')) {
            return app(DatabaseSearch::class);
        } else {
            return app(AlgoliaSearch::class);
        }

    }
}
class AlgoliaSearch implements SearchInterface
{

    
    public function __construct()
    {
        $this->strategy = app(AlgoliaSearchFactory::class)->create();
    }
    public function search()
    {
        $this->strategy->search();
    }
}
class AlgoliaSearchFactory
{

    public function create()
    {
        if (request('type') == 'thread') {
            return app(Threads::class);
        } elseif (request('type') == 'profile_post') {
            return app(ProfilePosts::class);
        } elseif (request()->missing('type')) {
            return app(AllPosts::class);
        } elseif (request()->boolean('only_title')) {
            return app(Thread::class);
        }
    }
}

Where the classes created in the AlgoliaSearchFactory are algolia aggregators so the search method can be called on any of those classes.

Would something like this make it cleaner or even worse ?

Right now i have strategies that have strategies which sounds too much to me.

Activity icon

Replied to Simplify Nested If Statements

@martinbean do you mean to create a strategy for each if statement ?

Activity icon

Started a new Conversation Simplify Nested If Statements

I'm implementing a search functionality and based on the query parameter i use a different class to search.

class Search { 
	if (request('type') == 'thread') {
    		$results = app(SearchThreads::class)->query();
	}elseif (request('type') == 'profile_post') {
                $results = app(SearchProfilePosts::class)->query();
        } elseif (request()->missing('type')) {
               $results = app(SearchAllPosts::class)->query();
       }

}

Now when i want to search threads i have the following code.

class SearchThreads{

        $searchQuery = request('q');
        $onlyTitle = request()->boolean('only_title');

        if (isset($searchQuery)) {
            if ($onlyTitle) {
                $query = Thread::search($searchQuery);
            } else {
                $query = Threads::search($searchQuery);
            }
        } else {
            if ($onlyTitle) {
                $query = Activity::ofThreads();
            } else {
                $query = Activity::ofThreadsAndReplies();
            }
        }

}

To explain the code.

If the user enters a search word ( $searchQuery) then use Algolia to search, otherwise make a database query directly.

  • If the user enters a search word

    1. Use the Thread index if the user has checked the onlyTitle checkbox
    2. Use the Threads index if the user hasn't checked the onlyTitle checkbox
  • If the user doesn't enter a search word

    1. Get all the threads if the user has checked the onlyTitle checkbox
    2. Get all the threads and replies if the user hasn't checked the onlyTitle checkbox

Is there a pattern to simplify the nested if statements or should i just create a separate class for the cases where

  1. a user has entered a search word
  2. a user hasn't entered a search word

And inside each of those classes to check if the user has checked the onlyTitle checkbox

Sep
28
3 weeks ago
Activity icon

Started a new Conversation Algolia Scout Complex Where Clauses And Eager Loading

Since Laravel Scout doesn't support more complex where clauses than simple numeric comparisons.

I checked the source code and I found the following lines

if (!empty($models = $model->getScoutModelsByIds($builder, $modelKeys))) {
                    $instances = $instances->merge($models->load($searchable->getRelations($modelClass)));
                }

The instances is what is returned from Algolia search, so for example the following search essentially returns the $instances variable.

Mode::search('something')->get();

the $model is the searchable model and the getScoutModelsByIds what It basically does is a query to the database like

public function getScoutModelsByIds(){
       $model->whereIn('id', $modelKeys)->get();
}

I was wondering if I apply any kind of where clauses or addSelect, or with eager loading, on the model before actually retrieving the data from the database, is it a good idea ?

For example

$model->where('some condition')->whereIn('id', $modelKeys)->get();

and instead of using lazy loading

$instances = $instances->merge($models->load($searchable->getRelations($modelClass)));

use the with function before retrieving the data from db.

For example

$model->where('some condition')->whereIn('id', $modelKeys)->with('relationships')->get();
Sep
27
4 weeks ago
Activity icon

Started a new Conversation Where Clause On New Column

Given that I have two models

ModelA and ModelB

If I want to query ModelA and add a new column based on ModelB and finally apply a where clause on the new column outside the addSelect

ModelA::addSelect([“new_column” => ModelB::select(“new_column”)->whereColumn(“tableA.id”, “tableB.id”)])->where(“new_column”,  value)

Is there a way to do this ?

Sep
26
4 weeks ago
Activity icon

Replied to Can't Use Where Clause After Union Of 2 Queries

Sorry for the confusion but when i said eager loading i had laravel in my mind which creates a collection with the eager loaded relationship.

So if i do

SELECT t1.*, t2.* 
FROM table1 t1,
           table2 t2
WHERE t1.id = t2.table1_id;

Then the result will be

table1.id
table1.created_at
table2.id
table2.created_at

But when you use

Table1::with('table2')->get()

the result is

table1.id
table1.created_at
table2 => [
	table2.id
	table2.created_at
]

So i guess that technically yes with the database view you do eager load the relationships that you need but are not nested like in a laravel collection structure like the example above.

I understand that it's hard to grasp what i'm trying to do without giving more information but if i do then i would have to write a lot and i don't know if anybody would be willing to read all that information.

Using eloqunt in my case the ideal solution would be to have access to thread and reply and apply where clauses and add select on them.

->with(['subject' => function (MorphTo $morphTo) {
                $morphTo->morphWith([
                     Thread::class => ['poster', 'category'],
                     Reply::class => ['repliable' => function

So from the code above what i would need ideally would be

->with(['subject' => function (MorphTo $morphTo) {
                $morphTo->morphWith([
                     Thread::class => function($builder){
                        $builder->where('some condiiton')
                            ->addSelect('some column')
                            ->with('some relationship')
                    },
                    Reply::class => function($builder){
                        $builder->where('some condiiton')
                            ->addSelect('some column')
                            ->with('some relationship')
                    }
                    ],
Activity icon

Replied to Can't Use Where Clause After Union Of 2 Queries

That is an interesting approach.

However in my case i use nested eager loading.

In your case as far as i understand you can use eager loading on BookCollectionView, but can you load nested relationships ?

To better explain this, in my case i have the activities table with a polymorphic relationship

activities
- subject_id
- subject_type

Now when i eager load the subject relationship, i want also to load other nested relationships which can also be polymorphic.

This is one of the queries that i want to eventually union it with other queries.

$query->whereHasMorph('subject', ['App\Reply'], function ($builder) {
    $builder->onlyReplies();
})->addSelect(
    [
        'replies_count' => Thread::select('replies_count')
            ->whereRaw('threads.id=(SELECT repliable_id from replies where replies.id=activities.subject_id)'),
    ]
)->with(['subject' => function ($builder) {
    $builder->with(['repliable' => function (MorphTo $morphTo) {
        $morphTo->morphWith([
            Thread::class => ['poster', 'category'],
            ProfilePost::class => ['profileOwner'],
        ]);
    }])->addSelect(
        [
            'replies_count' => Thread::select('replies_count')
                ->whereColumn('threads.id', 'replies.repliable_id'),
        ]);
}]);

As you can see i load the subject relationship which is a reply in this case, and then i want to load the repliable relationship which can be either a Thread or a ProfilePost, and then i load a relationship for each one of the aforementioned. Finally i'm adding an extra column named replies_count on both subject and reply model.

As a conclusion, if i'm not mistaken, i cannot use your approach with the database view because i don't want to just load a relationship on the final model ( the BookCollectionView in your case )

For example

BookCollectionView->with('relationship');

but instead i need to use nested relationships.

Activity icon

Replied to Can't Use Where Clause After Union Of 2 Queries

@tray2

Thanks!

I can filter out the queries individually before using union, however i'm trying to avoid this approach and instead follow your second approach.

But I'm trying to figure out how i can apply your second approach using laravel builder because i'm also eager loading relationships and i haven't found a solution yet.

Activity icon

Replied to Can't Use Where Clause After Union Of 2 Queries

so far the only way to make it work is using union.

i'm still trying to figure out if i can do it in 1 query and avoid union

Sep
25
1 month ago
Activity icon

Replied to Can't Use Where Clause After Union Of 2 Queries

Thank you.

I tried to figure out how to do with as a subquery but the only thing that i found is

$finalQuery = $query1->union($query2);

$unionQuery = DB::table(DB::raw("({$finalQuery->toSql()}) as activities"))->select('*')->mergeBindings($finalQuery->getQuery())

The problem with this one is that all the relationships that i eager loaded in $query1 and $query2 are lost and additionally i can't load any relationship with this query

This doesn't work

$unionQuery->with('relationship')->get();

Any thoughts ?

Sep
24
1 month ago
Activity icon

Started a new Conversation Can't Use Where Clause After Union Of 2 Queries

i have 2 queries and i apply union and finally use a where clause to filter the final query. This doesn't seem to work though. Is this normal ? Or i'm missing something ?

I have to mention that the columns are the same so the union doesn't fail, is just that i cannot apply any where clause after i union 2 queries.

This doesn't work

$query1 = 'some query';
$query2 = 'some query';

$finalQuery = $query1->union($query2);

$finalQuery->where('some condition');

However, if i apply the where clause before i union the 2 queries then everything works.

$query1 = 'some query';
$query2 = 'some query';
$query1->where('some condition');
$query2->where('some condition');

$finalQuery = $query1->union($query2);

Sep
23
1 month ago
Activity icon

Started a new Conversation Override Pagination Data

when i query the activities table and eager load a relationship, i want the paginated data to contain only the relationship data and not the activity data.

array:12 [
  "current_page" => 1
  "data" => array:1 [
    0 => array:8 [
      "id" => 1
      "user_id" => "1"
      "type" => "created-thread"
      "subject_id" => "1"
      "subject_type" => "App\Thread"
      "created_at" => "2020-09-23T22:15:34.000000Z"
      "updated_at" => "2020-09-23T22:15:34.000000Z"
      "subject" => array:19 [
        "id" => 1

The subject is the eager loaded relationship and i need only the subject data

I know that i can grab the subject using pluck('subject')

collect($paginated)->pluck('subject');

but i can't figure out how to replaced the original paginated data with subjects

Essentially what i want to achieve is the following

$paginated['data'] = $paginated->pluck('subject')

And then finally return $paginated to the view.

Sep
21
1 month ago
Activity icon

Replied to Set Searchable Attributes To Algolia

@bobbybouwmann

Do the where clauses apply to the index or to the records that are retrieved from the database ?

$articles = Article::search('Star Trek')->where('views', '>', 100)->get();
Sep
18
1 month ago
Activity icon

Started a new Conversation Service Container Use Case

I have a class ThreadFilters and a class ManageFilters.

The class ManageFilters stores an array of filter classes and iterates over the array and executes the filters. ( the filters are where functions for querying.

Class ManageFilters {

Protected filters = [];

public function addFilter($filter){
       $this->filters[] = $filter;
}

public function apply($builder){
       foreach($this->filters as $filterClass){
        $filter = app($filterClass);
       }
}


}

In the ThreadController I will have then to instantiate the ManageFilters and then add the ThreadFilters

app(ManageFilters::class)->addFilter(ThreadFilters::class)

Instead using the service container I can do


  $this->app->bind('ThreadFilter', function ($app) {
            $manageFilters = app(ManageFilters::class);
            $manageFilters->addFilter(ThreadFilters::class);
            return $manageFilters;
        });

And in the controller I can do


$filtters = app(‘ThreadFilter’);

Is this a good use case for service container ? Or I’m getting it wrong ?

Sep
15
1 month ago
Activity icon

Started a new Conversation Eager Load Relations Of Morphed Models In Algolia

I'm using the scout extended because i have multiple models in one index ( i'm using aggregators )

The aggregator is

class AllPosts extends Aggregator
{
    /**
     * The names of the models that should be aggregated.
     *
     * @var string[]
     */
    protected $models = [
        'App\Thread',
        'App\Reply',
        'App\ProfilePost',
    ];



    protected $relations = [
        ProfilePost::class => ['poster', 'profileOwner'],
        Thread::class => ['poster', 'category'],
        Reply::class => [
            'poster',
            'repliable.category',
            'repliable.profileOwner',
        ],
    ];

A Reply is a moph model and has the repliable relationship which can be either a Thread or a ProfilePost.

For the ProfilePost i need to eager load also the profileOwner

For the Thread i need to eager load also the category

Unfortunately this can't be done because when i have a Reply with repliable Thread it tries to eager load the profileOwner which exists only for the ProfilePost.

I can't figure out a way to use morphWith.

Is there an alternative way to achieve that with algolia ?

Sep
14
1 month ago
Activity icon

Replied to Authenticated User Is Not Found In Boot Method

i was about to do it but eventually i didn't upgrade because i'm using a package that doesn't support laravel 8.

does this have to do with the issue that i'm facing ?

should i upgrade ?

Activity icon

Started a new Conversation Authenticated User Is Not Found In Boot Method

I have a trait which is shared among different models and in the boot method of the trait i check whether there is an authenticated user. This used to work perfectly fine but i have no idea what i might have done since i haven't touched that part for a while, but it doesn't work now.

trait RecordsActivity
{
    /**
     * Boot the trait
     */
    public static function bootRecordsActivity()
    {
        if (!auth()->check()) {
            return;
        }
}

the authenticated user is null always

trait RecordsActivity
{
    /**
     * Boot the trait
     */
    public static function bootRecordsActivity()
    {
	dd(auth()->user());
    }
}

any thoughts ?

Sep
13
1 month ago
Activity icon

Started a new Conversation Algolia Paginate Multiple Models

I created an aggregator to combine multiple models on the same index.

class ThreadsReplies extends Aggregator
{
    /**
     * The names of the models that should be aggregated.
     *
     * @var string[]
     */
    protected $models = [
        Thread::class,
        Reply::class,
    ];
}

I want to be able to paginate the results but I see on the documentation that this is not supported.

ThreadsReplies::search('something')->paginate();

Is there a workaround or a package that can help me to achieve that ?

Sep
12
1 month ago
Activity icon

Replied to Set Searchable Attributes To Algolia

i just noticed that the toSearchableArray() does not apply anymore to the index which is used only to search the thread's title, but it does work for the aggregator ( which consists of the Thread and Reply models)

Activity icon

Replied to Set Searchable Attributes To Algolia

it seems like there is no pagination for the aggregator index.

Is there a package or another solution to this ?

Activity icon

Replied to Set Searchable Attributes To Algolia

@bobbybouwmann

Thanks for the idea. I created 2 indices for the same model ( 1 of them is aggregator actually )

In my case, i want to search all attributes for threads and replies and that's why i created an aggregator to combine both models in 1 index.

Then i created another index only for the Thread. Then from the dashboard i set the searchable attribute to be only the title

So it is possible to create 2 indices and use the same model, at least when 1 of them is aggregator.

Activity icon

Replied to Set Searchable Attributes To Algolia

I just found this article for anyone who faces the same issue.

https://protone.media/en/blog/search-through-multiple-eloquent-models-with-our-latest-laravel-package

I haven’t tried it yet.

Activity icon

Started a new Conversation Set Searchable Attributes To Algolia

I'm trying to figure out how I can set the searchable attributes to an index during runtime.

I have the model Thread which is searchable and based on a query parameter, I want to search only the title of the index.

class Thread extends Model 
{
	use Searchable;
}

What I have tried :

1

if (request('only_title')){
	Thread::search('query', [
                'restrictSearchableAttributes' => [
                    'title',
                ],
}

2

Thread::setSettings(
  [
    'restrictSearchableAttributes' => ['title']
  ],

3

There is also a configuration file named scout-threads where I can set the restrictSearchableAttributes value.

config('scout-threads.restrictSearchableAttributes', 'title');

Any thoughts ?

Sep
10
1 month ago
Activity icon

Replied to Not Reading .env File

@automica

i saw that on a Jeffrey's video that's why i did it but maybe i'm missing something.

I wrote it here because i thought that it might be related to this discussion

scout.php

return [
 'driver' => env('SCOUT_DRIVER', 'algolia'),
]
Activity icon

Replied to Not Reading .env File

the Algolia keys have no special characters.

I also noticed that when I set an env variable in phpunit.xml and I try to use config in a test to change that value, the value doesn't change.

phpunit.xml

<server name="SCOUT_DRIVER" value="null"/>
use Tests\TestCase;

class SearchTest extends TestCase
{
	/** @test */
	public function search_threads(){

	config(['scout.driver' => 'algolia']);

	dd(env('SCOUT_DRIVER'));

}

I still get null when I dd

Activity icon

Replied to Not Reading .env File

i just did.

yes it is, i do get results

even when i search specifically for the id of the algolia key i do get result.

config('scout.algolia.id');
Activity icon

Replied to Not Reading .env File

i have no issues with the other .env variables

only with the algolia keys, which are the most recent ones.

Activity icon

Started a new Conversation Not Reading .env File

I was about to set up algolia, i copied the keys to .env but when i tried to

php artisan scout:import 

I get error, that the ALGOLIA keys are invalid.

When i copied the keys in the scout.php configuration file, the

php artisan scout:import 

worked.

Also i tried to get the environment variables from php artisan tinker and i had not issues.

Finally, I executed in different order

php artisan config:cache
php artisan config:clear
php artisan cache:clear

But i still get the same error.

Any thoughts ?

Sep
06
1 month ago
Activity icon

Started a new Conversation Eager Load Nested Relationship If Exists

Is there a way to eager load a nested relationship only if exists ?

I have a polymorphic relationship with the models

activity

  • id
  • subject_id
  • subject_type

class Activity extends Model {

public function subject(){
	return $this->morphTo();
}

}

and then i have the models ( among others ) Thread and Like

class Thread extends Model {

	public function poster(){
		return $this->belongsTo('App\User');
	}
}

In this case i want to eager load the relationship poster only if it exists.

The model Thread does have a relationship named poster but the model Like doesn't

Activity::with('subject.poster')->get();

I don't want to globally eager load the relationship because it will add unnecessary queries in other views.

Sep
04
1 month ago
Activity icon

Started a new Conversation Push Mail And Database Notifications In Different Queues

For each notification i use 2 different channels ( database and mail )

What i want, is to push the mail notifications in a different queue in order to prioritise the database notifications.

Should i create 2 different notification classes or is there a different way to achieve that ?

Aug
30
1 month ago
Activity icon

Replied to Display Different Type Of Notifications

my bad

i was using the name data which is occupied.

i changed it to notificationData and it worked

Activity icon

Replied to Display Different Type Of Notifications

that's what i thought but i just noticed that i can't even use the same property name for the same component in a v-for.

i get the following error

The computed property "data" is already defined as a prop.

and i have only one notification component in the v-for


<div @click="markAsRead(notification.id)”
            v-for="(notification, index) in notifications"
            :key="notification.id"
            class="dropdown-item"
          >
            <reply-notification v-if="isReply(notification)" :data="notification.data"></reply-notification>
     
          </div>
Activity icon

Started a new Conversation Display Different Type Of Notifications

I have different type of notifications ( each type has a different message )

The notifications are stored in the database and one of the data that I store is the type which has a string value and is manually set by me in order to distinguish the notifications

I’m looping through the undead notifications of the user and based on the type I want to load the respective Vue component which displays a message.


<div           @click="markAsRead(notification.id)”
            v-for="(notification, index) in notifications"
            :key="notification.id"
            class="dropdown-item"
          >
            <reply-notification v-if="isReply(notification)" :data="notification.data"></reply-notification>
            <like-notification v-if=“isLike(notification)” :data="notification.data"></like-notification>
          </div>


    isReply(notification) {
      return notification.data.type == "reply";
    },
    isLike(notification) {
      return notification.data.type == “like”;

The issue that I am facing is that I cannot pass the same prop name in every notification component, which is the name data.

Is there any workaround to this issue or any idea how to present different notifications based on the type of the notification

Activity icon

Started a new Conversation Delay Because Of The Notifications

I'm building a small forum app and when i post something, a notification is sent to the respective users.

I noticed that there is a delay when i post something and i found out that it is because of the notifications that are being sent.

Currently i have both mail and database notifications.

If i remove the mail notifications

  • Less queries are executed and the delay is gone.

With the mail notifications, the Queueable trait and the ShouldQueue interface .

  • More queries are executed and the delay is there.

With the mail notifications, If i remove the Queueable trait and the ShouldQueue interface.

  • Less queries are executed but the delay is still there.
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;

class ProfileHasNewPost extends Notification implements ShouldQueue
{
    
    use Queueable;

Any idea how avoid the delay ?