JanPe

Member Since 1 Year Ago

Oldenburg

Experience Points
2,430
Total
Experience

2,570 experience to go until the next level!

In case you were wondering, you earn Laracasts experience when you:

  • Complete a lesson — 100pts
  • Create a forum thread — 50pts
  • Reply to a thread — 10pts
  • Leave a reply that is liked — 50pts
  • Receive a "Best Reply" award — 500pts
Lessons Completed
23
Lessons
Completed
Best Reply Awards
0
Best Reply
Awards
  • start your engines Created with Sketch.

    Start Your Engines

    Earned once you have completed your first Laracasts lesson.

  • first-thousand Created with Sketch.

    First Thousand

    Earned once you have earned your first 1000 experience points.

  • 1-year Created with Sketch.

    One Year Member

    Earned when you have been with Laracasts for 1 year.

  • 2-years Created with Sketch.

    Two Year Member

    Earned when you have been with Laracasts for 2 years.

  • 3-years Created with Sketch.

    Three Year Member

    Earned when you have been with Laracasts for 3 years.

  • 4-years Created with Sketch.

    Four Year Member

    Earned when you have been with Laracasts for 4 years.

  • 5-years Created with Sketch.

    Five Year Member

    Earned when you have been with Laracasts for 5 years.

  • school-in-session Created with Sketch.

    School In Session

    Earned when at least one Laracasts series has been fully completed.

  • welcome-newcomer Created with Sketch.

    Welcome To The Community

    Earned after your first post on the Laracasts forum.

  • full-time-student Created with Sketch.

    Full Time Learner

    Earned once 100 Laracasts lessons have been completed.

  • pay-it-forward Created with Sketch.

    Pay It Forward

    Earned once you receive your first "Best Reply" award on the Laracasts forum.

  • subscriber Created with Sketch.

    Subscriber

    Earned if you are a paying Laracasts subscriber.

  • lifer Created with Sketch.

    Lifer

    Earned if you have a lifetime subscription to Laracasts.

  • evangelist Created with Sketch.

    Laracasts Evangelist

    Earned if you share a link to Laracasts on social media. Please email [email protected] with your username and post URL to be awarded this badge.

  • chatty-cathy Created with Sketch.

    Chatty Cathy

    Earned once you have achieved 500 forum replies.

  • lara-veteran Created with Sketch.

    Laracasts Veteran

    Earned once your experience points passes 100,000.

  • 10k-strong Created with Sketch.

    Ten Thousand Strong

    Earned once your experience points hits 10,000.

  • lara-master Created with Sketch.

    Laracasts Master

    Earned once 1000 Laracasts lessons have been completed.

  • laracasts-tutor Created with Sketch.

    Laracasts Tutor

    Earned once your "Best Reply" award count is 100 or more.

  • laracasts-sensei Created with Sketch.

    Laracasts Sensei

    Earned once your experience points passes 1 million.

  • top-50 Created with Sketch.

    Top 50

    Earned once your experience points ranks in the top 50 of all Laracasts users.

  • Community Pillar

    Earned once your experience points ranks in the top 10 of all Laracasts users.

Level 1
2,430 XP
Apr
08
1 week ago
Activity icon

Replied to N+1 Query Problem With Nested JsonResources

Okay, i checked it again.

This solution does not work:

class User ...
{
    protected $with = [
        'setting',
        'setting.user',
    ];
}

public function index(): ResourceCollection
{
	return UserResource::collection(
		User::query()->paginate()
	);
}

class SettingResource extends JsonResource
{
    public function toArray($request)
    {
        return [
           'id' => $this->id,
           'user_id' => $this->whenLoaded('user', fn() => $this->user->id, null),
           'foo' => 'bar',
    }
}

And this solution does it

class User ...
{
    protected $with = [

    ];
}

public function index(): ResourceCollection
{
	return UserResource::collection(
		User::with(['setting', 'setting.user'])->paginate()
	);
}

But I don't understand why one thing works and the other doesn't: D When I debug the eloquent model, $ with is correctly set by the model and transferred to the QueryBuilder

Activity icon

Replied to N+1 Query Problem With Nested JsonResources

Thank you for your explanation. In my user model I already indicate the loading of setting with

    protected $with = [
        'setting',
    ];

Does that make any difference to that User::with('setting')->paginate($user) ?

I've already tried to check whether the relationship has been loaded, but it doesn't make any difference

class SettingResource extends JsonResource
{
    public function toArray($request)
    {
        return [
           'id' => $this->id,
           'user_id' => $this->whenLoaded('user', $this->user->id),
           'foo' => 'bar',
    }
}
Apr
07
1 week ago
Activity icon

Started a new Conversation N+1 Query Problem With Nested JsonResources

Hello,

i have a user and setting model, in my case a user and setting have a 1:1 relation. For each model there is a CRUD API endpoint, e.g. for better understanding /api/users and /api/users/{user}/settings

This endpoints returns a JsonResource. The user resource includes the setting resource on index and show GET request. (See code snippets below)

The problem i figured out was, that i trigger the n+1 problem in the SettingResource with $this->user->id. If i replace this with the foreign key $this->user_id everything is working fine and i have no n+1 problem.

Sound's logically and for now i have fixed my problem. But i want to understand how can i avoid this n+1 Problem in this $this->user->* case? Maybe in a next feature the SettingResource should return the user's email and $this->user->email triggers the error again.

maybe someone can help me

class UserResource extends JsonResource
{
    public function toArray($request)
    {
        return [
            'id'         => $this->id,
            'email'      => $this->email,
            'locale'     => $this->locale,
            'settings'   => $this->whenLoaded('setting', SettingResource::make($this->setting)),
        ];
    }
}
class SettingResource extends JsonResource
{
    public function toArray($request)
    {
        return [
            'id'      => $this->id,
            'user_id' => $this->user->id,
           'foo' => 'bar',
    }
}
class User extends Model 
{
    protected $with = [
        'setting',
    ];

    public function setting(): HasOne
    {
        return $this->hasOne(Setting::class)->withDefault();
    }
}
class Setting extends Model
{
    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }
}
/** parts of the migration */
Schema::create('settings', function (Blueprint $table) {
    $table->uuid('id')->primary();
    $table->uuid('user_id');

    // some other fields

    $table->foreign('user_id')->references('id')->on('users')->cascadeOnDelete();

    $table->timestamps();
});

Schema::create('users', function (Blueprint $table) {
    $table->uuid('id')->primary();
    
    // some other fields

    $table->timestamps();
    $table->softDeletes();
});
public function index(): ResourceCollection
    {
        return UserResource::collection(
            User::query()->paginate($user)
        );
    }
Nov
02
5 months ago
Activity icon

Replied to How To Validate Field Name

You can write your own Validation Rule e.g.

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;

class CustomField implements Rule
{
    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        // attribute is here a dot notation of the full path e.g. custom_fields.lead_in
        // you can also put the dot path as parameter to this Class see https://laracasts.com/discuss/channels/laravel/create-custom-validation-rule-with-additional-parameters-implement-in-request

	$attribute = end(explode($attribute, '.');

        // check if $attribute is in Table and return a bool 
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return ':attribute is a unknown custom field'
    }
}

Your FormRequest:

return [
	...,
	'owner_id' => ['bail', 'integer', 'is_user'],
	'custom_fields' => ['array'],
	'custom_fields.*' => ['distinct', 'exists:custom_fields,api_key', new CustomField()],
];
Oct
30
5 months ago
Activity icon

Started a new Conversation REST API Design For HasMany POST/PUT

Hi guys,

I need your support in API design. First of all, I am well aware of RESTFul, Resources Eloquent Relations. But I always find it difficult to find the ideal way for myself, as I can handle a HasMany relationship for POST / PUT requests.

How do you solve this in your projects?

An example:

The Workouts entity has exercises as children. The endpoint /api/vX/workouts is corresponding to CRUD.

Response GET /api/vX/workouts

{
    "data": [
        {
            "name": "",
            "other_attributes": "",
            "exercises": [
                {
                    "id": "",
                    "other_attributes": ""
                }
            ]
        }
    ],
    "Meta": {}
}

What would a POST / PUT look like if you wanted to create a relationship between workouts and exercises? I would like to avoid nested resources if possible.

Do you add the foreign_id to in the body of GET /api/vX/workouts or would you add it as a query parameter?

POST /api/vX/workouts

{
  "name": "",
  "exercises": [
    {
	"id": "foreign_id"
    }
  ]
}

or like POST /api/vX/workouts?exercise_ids=id1,id2,id3,,,

I know "it depends", but what do you prefer? The natural order would be to create the parent "workout" first and then to create the childs "exercise" and thus the parent_id in the childs body.

POST /api/vX/workouts

{
  "name": "",
  "other_attributes": "",
}

POST /api/vX/exercises

{
	"id_workout": "parent_id",
	"name": "",
}