0

Currently I get data like so:

->with(['posts' => function ($query) {
            $query->active()->available()->limit(1)->with('user');
            }])

and it returns the user data as an array of objects which is expected. Because I am using a limit and will only ever need one result, I'd like to return it as a regular object, so instead of:

"data": value,
"posts": [
    {
      "data": value,
      "user": {
        "data": value
      }
    }
  ]

I'd like to return it as:

"data": value,
"post":
        {
          "data": value,
          "user": {
            "data": value
          }
        }

What's the best way to go about it?

2
  • Long shot here but try to replace limit(1) with first() Commented Jan 23, 2018 at 20:27
  • @FelippeDuarte Not a bad idea at all and was even suggested on other forms, but doing so seems to then not trigger the ->with('user') part, and still returns postsas an array :P Commented Jan 23, 2018 at 20:29

2 Answers 2

1

Create a hasOne association on your model that defines the scope you'd like.

public function activePost()
{
    return $this->hasOne(Post::class)->active()->available();
]

Then call with('activePost.user') to load that single, active and available post with it's associated user.

Sign up to request clarification or add additional context in comments.

4 Comments

Seems like an idea! Will this work even if there is a hasMany relationship already defined? I just ran into the error of first() literally returning just one result instead of one result for each parent object... any ideas?
Yes - they can live side-by-side, they would be totally independent of each other. You can't use first() inside of a with() scope query as someone suggest above because it is expecting a query back, not a model.
Would I need to write in a first() on the new association too?
Nope - because it's a hasOne Laravel knows you only want a single model. Give the code a run in your project and see how it goes for you.
1

As long as your relationship is a hasMany, hasManyThrough, belongsToMany, morphMany, morphedByMany relationship (I think that's all of them), eager loading will always return an array since the primary use of the with method is for adding clauses to a relationship.

Quoted from best answer on the laracasts forums: https://www.laracasts.com/discuss/channels/eloquent/first-and-take-do-not-work-correctly-in-eager-load-laravel?page=0)

@Dwight's answer is the right approach.

1 Comment

... and how is this an answer to the question?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.