skip to Main Content

In Message.php model:

    public function getAudioUrlAttribute()
    {
        return Storage::disk('public')->url('audio/' . $this->audio);
    }

in MessageController.php

        $messages = Message::select('id', 'role', 'content', 'audio')->get();
        $messages = $messages->map(function($message) {
            return $message->only('id', 'role', 'content', 'audio_url');
        });
        return ['messages' => $messages];

how to add audio_url to the return data elegantly? This is the only way I know, is there a better one?

5

Answers


  1. try this

    $messages = Message::select('id', 'role', 'content', 'audio')->get()->append('AudioUrl');
    
    Login or Signup to reply.
  2. Your current approach of using the map function to add the audio_url attribute to the Eloquent collection is perfectly fine, and it’s a common way to transform and add attributes to collections in Laravel. However, if you’re looking for an alternative or more concise way to achieve the same result, you can consider using Eloquent’s append property.

    Here’s how you can do it:

    1. In your Message.php model, define an appends property that includes the audio_url attribute:
    class Message extends Model
    {
        // ...
    
        protected $appends = ['audio_url'];
    
        public function getAudioUrlAttribute()
        {
            return Storage::disk('public')->url('audio/' . $this->audio);
        }
    
        // ...
    }
    

    By adding 'audio_url' to the appends property, you’re telling Laravel to automatically append the audio_url attribute to the JSON representation of the model.

    1. In your MessageController.php, simply retrieve the messages without specifying the attributes you want to select:
    $messages = Message::all(); // This retrieves all columns from the table
    return ['messages' => $messages];
    

    Now, when you return the $messages collection, it will automatically include the audio_url attribute without the need for additional transformation using map.

    This approach keeps your code more concise and takes advantage of Laravel’s built-in functionality for appending attributes to model instances when they are serialized to JSON.

    Login or Signup to reply.
  3. To get the audio URL of a message without using the append property in the model, use $message->audioUrl.

    Login or Signup to reply.
  4. If you want to append attribute globally,

    In Message.php model:

    protected $appends = array('audio_url');
    public function getAudioUrlAttribute()
    {
        return Storage::disk('public')->url('audio/' . $this->audio);
    }
    

    If you want to append it on specific time,

    $messages->append('audio_url');
    
    Login or Signup to reply.
  5. In your ‘Message.php‘ model, you can define an accessor for the ‘audio_url‘ attribute like this:

    public function getAudioUrlAttribute()
    {
        return Storage::disk('public')->url('audio/' . $this->audio);
    }
    

    By naming the method getAudioUrlAttribute, Laravel will automatically append the audio_url attribute to your Message model whenever you retrieve it.

    Then, in your MessageController.php, you can simply retrieve the messages without manually selecting the attributes:

    $messages = Message::all();
    return ['messages' => $messages];
    

    Now, when you access the audio_url attribute on a Message model, Laravel will automatically call the getAudioUrlAttribute method, and you’ll have the URL without the need for explicit mapping.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search