0

I have a mutator that converts the model's body in desired translated format.

public function getTextAttribute() {
   return $this->constructText($this->body); // which does __($key, $value)
}

protected $appends = ['text'];

However, once they are in the queued job, I can't change locale whatever I tried and even I pass an Eloquent Collection, it changes them to default locale too.

What I tried:

  1. Before firing the job, passing $locale and $eloquentCollection to the job.

    MyEvent::dispatch($collection, $language)
    

And in my job,

    public function __construct($collection, $language)
    {
       app()->setLocale($language);
       // if I log here, it logs the given locale as my current locale
       // but as soon as hits the get mutator, it goes back to default locale
    }

  1. In my collection, I tried putting a property:

    class MyModel extends Model {
       public $locale = null;
    
    }
    

And in my job,

    public function __construct($collection, $language)
    {
       app()->setLocale($language);

       $collection->each(function($item) {
           $item->locale = $language;
       })
    }

And changed the mutator to:

    public function getTextAttribute() {
       if (!$this->locale) { 
           $this->locale = app()->getLocale(); 
       }

       return $this->constructText($this->body, $this->locale); 
       // which does __($key, $value, $locale) inside
    }

However this didn't work either. When I log inside constructText() the $locale - it returns the default locale too.

Is there any way or workaround you can think of? 2 other possible workarounds came to my mind are:

  • Is there a way to prevent Eloquent models in collection to get mutated?

  • Is there a way to convert eloquent collection values (including 'text') to an object (without having connection to the actual models)? so I can give it directly to the job.

senty
  • 12,385
  • 28
  • 130
  • 260
  • 1
    you wouldn't be trying to set the app locale in the constructor, which is ran when you create the job/dispatch it, it doesn't get called after it is unserialized (when a worker gets to run it), you would need to call that in the `handle` method – lagbox Dec 14 '19 at 20:35
  • It is a Broadcasting Event, so the methods I have are `broadcastOn()`, `broadcastAs()` and `__construct()`. Where should I include it? Is `broadcastWith()` a good place for this? – senty Dec 14 '19 at 20:37
  • do you have a listener class or is this handling itself? because you keep saying 'job' – lagbox Dec 14 '19 at 20:40
  • It's handling itself - App\Events\MyEvent `MyEvent implements ShouldQueue` type. – senty Dec 14 '19 at 20:44
  • 1
    Anyhow, _"you wouldn't be trying to set the app locale in the constructor, which is ran when you create the job/dispatch it, it doesn't get called after it is unserialized"_ that made it very clear - I made it work with `broadcastWith()`. Thank you! – senty Dec 14 '19 at 20:48
  • 1
    sweet, that is one way to do it ... would be nice if there was something more like a handle method but anything that gets called from the job side would work good :) – lagbox Dec 14 '19 at 20:53
  • Feel free to add an answer, you literally saved me a day. Thanks again – senty Dec 14 '19 at 21:01

1 Answers1

1

The constructor of the Event is only called when you create the new instance of the event to then be fired/dispatched. When the job that contains this event that needs to be broadcast gets ran it only has the serialized payload to work with. You would need to try to set the locale or anything like that in a method that is called by the job's handle method. These broadcasted events will have the broadcastAs, broadcastOn and broadcastWith methods called by the handle method of the queue job. You should be able to set what you need in one of those methods since they will be run by the queue job which is ran by the worker, so it isn't not part of the original request lifecycle (unless the event has implemented ShouldBroadcastNow, as that would use the sync driver not the queue workers).

lagbox
  • 48,571
  • 8
  • 72
  • 83