Laravel多模型关系返回计数

I have three models:

User:

public function projects()
{
    return $this->hasMany('StoredFile', 'user_id', 'id')->with('files');
}

StoredFile:

public function files()
{
    return $this->hasMany('File', 'hash', 'user_hash');
}

and File models which does not have relation method

The problem:

I use the following piece of code to get projects and each project stored files:

$projects = $user->projects;
var_dump(json_encode($projects))
// {"project_name":"test","user_hash":"64650458b6Fhgd68ca57308222","files":[{"id":1,"name":"example.pdf"}]}

I can use count($projects[0]->files) to get files count

but this $projects variable need to return to client side by Response::json

return Response::json($project);

and I can't leak the files to the visitor, I want to modify the StoredFile model to return files count only

just like:

return $this->hasMany('File', 'hash', 'user_hash')->count();

but this will throw me an error:

Call to a member function addEagerConstraints() on a non-object"

How can I receive the count value in relations??

please help! thanks

Relationship methods must return an object of type Illuminate\Database\Eloquent\Relations\Relation. There is nothing wrong with your files() function, but it is not a relationship, so it can't be used in your projects() functions.

The problem piece of code is with('files'), as Laravel is expecting an object of type Illuminate\Database\Eloquent\Relations\Relation to be returned from the files() function, and instead it receives an int.

You can manually add this value to the model though. Try adding this to your StoredFile model:

public function fileCount() {
  return $this->hasMany('File', 'hash', 'user_hash')->count();
}

Change the User model:

public function projects() {
  return $this->hasMany('StoredFile', 'user_id', 'id');
}

Now use:

$projects = $user->projects;
$project = $project->first();
$project->fileCount = $project->fileCount();
var_dump(json_encode($project));
// {..., "fileCount":"1"}

Bare in mind that the number of files is being queried from the database once everytime you ask for it, so this is not efficient if you need to return more than one project. Given that you were returning a JSON response, I assumed that this would be the case though!

Otherwise, why not just do something like this:

public function files() {
  return $this->hasMany('File', 'hash', 'user_hash');
}

public function projects() {
  return $this->hasMany('StoredFile', 'user_id', 'id')->with('files');
}

Now use:

$projects = $user->projects;
$project = $project->first();
$project->fileCount = $project->files->count();
unset($project->files);
var_dump(json_encode($project));
// {..., "fileCount":"1"}

Something like that should work?

@Warren Moore is almost correct, but I just found a better solution:

protected $appends = array('file_count');

public function getFileCountAttribute()
{
   return $this->files->count()
}

this will append a file_count attribute to each file object