Home > Back-end >  Laravel relationship - set array key to name from column
Laravel relationship - set array key to name from column

Time:04-21

I apologize in advance for my not good English.

My model's: Article, Image and Image child's

Article:

class Article extends Model
{

    public function image()
    {
        return $this->hasOne(Image::class, 'id');
    }

}

Image:

class Image extends Model
{

    public function images()
    {
        return $this->hasMany(ImageChild::class);
    }

}

ImageChild:

class ImageChild extends Model
{

    public function image()
    {
        return $this->belongsTo(Image::class);
    }

}

After using:

$articles = Article::with('image.images')->orderBy('id', 'desc')->take(6)->get()->toArray();

return dd($articles);

return for example:

5 => array:9 [▼
    "id" => 2
    "title" => "Lorem ipsum"
    "slug" => "Lorem ipsum"
    "content" => "Lorem ipsum"
    "user_id" => 1
    "image_id" => 3
    "created_at" => "2022-04-19T10:04:12.000000Z"
    "updated_at" => "2022-04-19T10:04:12.000000Z"
    "image" => array:5 [▼
      "id" => 2
      "alt" => "Lorem ipsum"
      "created_at" => "2022-04-19 06:30:41"
      "updated_at" => "2022-04-19 06:30:41"
      "sizes" => array:7 [▼
        0 => array:8 [▼
          "id" => 8
          "name" => "s8UUjBlvjWjZHBHjFSqeNhJuo4AlLd"
          "ext" => "png"
          "src" => "/images/upload/2022/2/s8UUjBlvjWjZHBHjFSqeNhJuo4AlLd_large.png"
          "size" => "large"
          "image_id" => 2
          "created_at" => "2022-04-19 06:30:42"
          "updated_at" => "2022-04-19 06:30:42"
        ]
        1 => array:8 [▼
          "id" => 9
          "name" => "s8UUjBlvjWjZHBHjFSqeNhJuo4AlLd"
          "ext" => "png"
          "src" => "/images/upload/2022/2/s8UUjBlvjWjZHBHjFSqeNhJuo4AlLd_banner.png"
          "size" => "banner"
          "image_id" => 2
          "created_at" => "2022-04-19 06:30:42"
          "updated_at" => "2022-04-19 06:30:42"
        ]
        2 => array:8 [▼
          "id" => 10
          "name" => "s8UUjBlvjWjZHBHjFSqeNhJuo4AlLd"
          "ext" => "png"
          "src" => "/images/upload/2022/2/s8UUjBlvjWjZHBHjFSqeNhJuo4AlLd_slide.png"
          "size" => "slide"
          "image_id" => 2
          "created_at" => "2022-04-19 06:30:42"
          "updated_at" => "2022-04-19 06:30:42"
        ]
        3 => array:8 [▼
          "id" => 11
          "name" => "s8UUjBlvjWjZHBHjFSqeNhJuo4AlLd"
          "ext" => "png"
          "src" => "/images/upload/2022/2/s8UUjBlvjWjZHBHjFSqeNhJuo4AlLd_cover.png"
          "size" => "cover"
          "image_id" => 2
          "created_at" => "2022-04-19 06:30:42"
          "updated_at" => "2022-04-19 06:30:42"
        ]
        4 => array:8 [▼
          "id" => 12
          "name" => "s8UUjBlvjWjZHBHjFSqeNhJuo4AlLd"
          "ext" => "png"
          "src" => "/images/upload/2022/2/s8UUjBlvjWjZHBHjFSqeNhJuo4AlLd_thumbnail.png"
          "size" => "thumbnail"
          "image_id" => 2
          "created_at" => "2022-04-19 06:30:42"
          "updated_at" => "2022-04-19 06:30:42"
        ]
        5 => array:8 [▼
          "id" => 13
          "name" => "s8UUjBlvjWjZHBHjFSqeNhJuo4AlLd"
          "ext" => "png"
          "src" => "/images/upload/2022/2/s8UUjBlvjWjZHBHjFSqeNhJuo4AlLd_small.png"
          "size" => "small"
          "image_id" => 2
          "created_at" => "2022-04-19 06:30:42"
          "updated_at" => "2022-04-19 06:30:42"
        ]
        6 => array:8 [▼
          "id" => 14
          "name" => "s8UUjBlvjWjZHBHjFSqeNhJuo4AlLd"
          "ext" => "png"
          "src" => "/images/upload/2022/2/s8UUjBlvjWjZHBHjFSqeNhJuo4AlLd_mobile.png"
          "size" => "mobile"
          "image_id" => 2
          "created_at" => "2022-04-19 06:30:42"
          "updated_at" => "2022-04-19 06:30:42"
        ]
      ]
    ]
  ]

My goal is set array key in (main array -> image -> sizes) all of the child's from [0,1,2,3...] to name of size like:

...
"sizes" => array:7 [▼
        "large" => array:8 [▼
          "id" => 8
          "name" => "s8UUjBlvjWjZHBHjFSqeNhJuo4AlLd"
          "ext" => "png"
          "src" => "/images/upload/2022/2/s8UUjBlvjWjZHBHjFSqeNhJuo4AlLd_large.png"
          "size" => "large"
          "image_id" => 2
          "created_at" => "2022-04-19 06:30:42"
          "updated_at" => "2022-04-19 06:30:42"
        ]
        "banner" => array:8 [▼
          "id" => 9
          "name" => "s8UUjBlvjWjZHBHjFSqeNhJuo4AlLd"
          "ext" => "png"
          "src" => "/images/upload/2022/2/s8UUjBlvjWjZHBHjFSqeNhJuo4AlLd_banner.png"
          "size" => "banner"
          "image_id" => 2
          "created_at" => "2022-04-19 06:30:42"
          "updated_at" => "2022-04-19 06:30:42"
        ]
        "slide" => array:8 [▼
          "id" => 10
          "name" => "s8UUjBlvjWjZHBHjFSqeNhJuo4AlLd"
          "ext" => "png"
          "src" => "/images/upload/2022/2/s8UUjBlvjWjZHBHjFSqeNhJuo4AlLd_slide.png"
          "size" => "slide"
          "image_id" => 2
          "created_at" => "2022-04-19 06:30:42"
          "updated_at" => "2022-04-19 06:30:42"
        ]
        "cover" => array:8 [▼
          "id" => 11
          "name" => "s8UUjBlvjWjZHBHjFSqeNhJuo4AlLd"
          "ext" => "png"
          "src" => "/images/upload/2022/2/s8UUjBlvjWjZHBHjFSqeNhJuo4AlLd_cover.png"
          "size" => "cover"
          "image_id" => 2
          "created_at" => "2022-04-19 06:30:42"
          "updated_at" => "2022-04-19 06:30:42"
        ]
        "thumbnail" => array:8 [▼
          "id" => 12
          "name" => "s8UUjBlvjWjZHBHjFSqeNhJuo4AlLd"
          "ext" => "png"
          "src" => "/images/upload/2022/2/s8UUjBlvjWjZHBHjFSqeNhJuo4AlLd_thumbnail.png"
          "size" => "thumbnail"
          "image_id" => 2
          "created_at" => "2022-04-19 06:30:42"
          "updated_at" => "2022-04-19 06:30:42"
        ]
        "small" => array:8 [▼
          "id" => 13
          "name" => "s8UUjBlvjWjZHBHjFSqeNhJuo4AlLd"
          "ext" => "png"
          "src" => "/images/upload/2022/2/s8UUjBlvjWjZHBHjFSqeNhJuo4AlLd_small.png"
          "size" => "small"
          "image_id" => 2
          "created_at" => "2022-04-19 06:30:42"
          "updated_at" => "2022-04-19 06:30:42"
        ]
        "mobile" => array:8 [▼
          "id" => 14
          "name" => "s8UUjBlvjWjZHBHjFSqeNhJuo4AlLd"
          "ext" => "png"
          "src" => "/images/upload/2022/2/s8UUjBlvjWjZHBHjFSqeNhJuo4AlLd_mobile.png"
          "size" => "mobile"
          "image_id" => 2
          "created_at" => "2022-04-19 06:30:42"
          "updated_at" => "2022-04-19 06:30:42"
        ]
      ]
...

I tried use function keyBy(), but I did not achieve the desired effect

I hope I have described the situation quite clearly

Any idea how this can be achieved?

Thank you very much in advance for each answer

CodePudding user response:

I found a solution, but I don't know if it's right. I will be grateful if someone comments this solution.

In model Image I added:

    protected $appends = ['sizes'];

    public function getSizesAttribute()
    {
      return $this->images()->get()->keyBy('size');
    }

Effect is:

  0 => array:9 [▼
    "id" => 4
    "title" => "Lorem ipsum dolor"
    "slug" => "lorem-ipsum-dolor"
    "content" => "Lorem ipsum dolor sit amet consectetur adipisicing elit. Quibusdam magnam maiores sapiente voluptatem quidem obcaecati iusto consequatur repellat, laborum aliqu ▶"
    "user_id" => 1
    "image_id" => 5
    "created_at" => "2022-04-19T11:30:23.000000Z"
    "updated_at" => "2022-04-19T11:30:23.000000Z"
    "image" => array:5 [▼
      "id" => 4
      "alt" => "Lorem ipsum dolor"
      "created_at" => "2022-04-19 06:31:27"
      "updated_at" => "2022-04-19 06:31:27"
      "sizes" => array:7 [▼
        "large" => array:8 [▼
          "id" => 22
          "name" => "u7osaVoZ5mb2ikEfl9aWWcloE0HOjL"
          "ext" => "jpeg"
          "src" => "/images/upload/2022/4/u7osaVoZ5mb2ikEfl9aWWcloE0HOjL_large.jpeg"
          "size" => "large"
          "image_id" => 4
          "created_at" => "2022-04-19 06:31:31"
          "updated_at" => "2022-04-19 06:31:31"
        ]
        "banner" => array:8 [▶]
        "slide" => array:8 [▶]
        "cover" => array:8 [▶]
        "thumbnail" => array:8 [▶]
        "small" => array:8 [▶]
        "mobile" => array:8 [▶]
      ]
    ]
  ]

What do you think about it?

CodePudding user response:

you can also use mapToGroups method to your sizes array. but before that you should convert that array to collection by using collect($yourArray)

Try like this

collect($yourArray)->mapToGroups(function($item) {
        return $item->size= $item;
    });
  • Related