欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

How to display many to many relation objects as array in a json output?

Here's my artist model:
class Artist extends Eloquent implements SluggableInterface {
    public function tags() {
        return $this->belongsToMany('Tag', 'tag_artist');
    }

ApiController:

class ApiController extends \BaseController {
    public function getArtist() {
        return Response::json(Artist::all());
    }
}

It prints every single db column in a json format. My question is how can i output many to many relation object as an array?

E.g. every artist has many categories and vice versa. In a json page i am printing list of artists and their categories, like that:

[{
  "id": 1,
  "name": "someName",
  "categories": [1, 2]
]}
Best Answer(As Selected By heihachi88)
JarekTkaczyk

@heihachi88 The best way to handle it is by using api transformers, that let you define the the way your resources are sent in your api. Otherwise you can define appends and hiddenon the model or use in-line conversion like shown by @thepsion5 .

protected $hidden = ['tags'];
protected $appends = ['tagsIds'];
public  function getTagsIdsAttribute()
{
    return $this->tags->modelKeys();
}

This will hide tags collection from the json output, append tags_ids pseudo property that will hold the array from the accessor getTagsIdsAttribute.

JarekTkaczyk

@heihachi88 Just eager load the relation:

class ApiController extends \BaseController {
    public function getArtist() {
        return Response::json(Artist::with('tags')->get());
    }
}
 
heihachi88

Thanks, but this way i won't get artists without tags? My output is:

[{"id":1,"title":"Danielle Pagac","image":"","text":"Ipsam","tags":[{"id":1,"title":"Prof. Treva Hoppe","pivot":{"artist_id":1,"tag_id":1}
}]

How can i display tags this way:

  "tags": [1, 2]

I want to omit the rest tag columns.

 
thepsion5
 thepsion5
2 years ago(126,125 XP)

If you're using PHP 5.5 or newer, you can do this:

$artists = Artists::with('tags')->get()->toArray();
$artists = array_map(function($artist)
{
    $artist['tags'] = array_column($artist['tags'], 'id');
});
return Response::json($artists);
 
heihachi88

@thepsion5, i got php 5.5, but i get error:

syntax error, unexpected 'return' (T_RETURN) 
 
RomainLanz

Missing a bracket in the code.

$artists = Artists::with('tags')->get()->toArray();
$artists = array_map(function($artist)
{
    $artist['tags'] = array_column($artist['tags'], 'id');
});

return Response::json($artists);
 
thepsion5
 thepsion5
2 years ago(126,125 XP)

Yep, my bad. Edited my response now and fixed the syntax error.

 
heihachi88

Now i got another error :))

array_map() expects at least 2 parameters, 1 given 

What should be in a callback?

 
JarekTkaczyk

@heihachi88 The best way to handle it is by using api transformers, that let you define the the way your resources are sent in your api. Otherwise you can define appends and hidden on the model or use in-line conversion like shown by @thepsion5 .

protected $hidden = ['tags'];
protected $appends = ['tagsIds'];
public  function getTagsIdsAttribute()
{
    return $this->tags->modelKeys();
}

This will hide tags collection from the json output, append tags_ids pseudo property that will hold the array from the accessor getTagsIdsAttribute.

 
heihachi88

@JarekTkaczyk thanks, but i am using Tag model in api also, if i hide title fields for artist json, then it won't show up in a tag json either..

 
JarekTkaczyk

@heihachi88 You didn't get the point. You hide tags collection in the artist model. It doesn't affect tag model in any way, so you will get it like usually.

 
heihachi88

@JarekTkaczyk aa, you mean to use this on Artist model. Let me try that.

 
heihachi88

@JarekTkaczyk thanks alot! Helped me.

 

来自  https://laracasts.com/discuss/channels/general-discussion/how-to-display-many-to-many-relation-objec...

普通分类: