EvergreenWebSystems

EvergreenWebSystems

Member Since 6 Months Ago

Experience Points
11,610
Total
Experience

3,390 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
113
Lessons
Completed
Best Reply Awards
0
Best Reply
Awards
  • start-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-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-token Created with Sketch.

    Subscriber

    Earned if you are a paying Laracasts subscriber.

  • lifer-token Created with Sketch.

    Lifer

    Earned if you have a lifetime subscription to Laracasts.

  • lara-evanghelist 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.

Level 3
11,610 XP
Jul
23
3 months ago
Activity icon

Replied to UpdateExistingWithPivot

thanks

Activity icon

Replied to UpdateExistingWithPivot

thanks

Jul
13
4 months ago
Activity icon

Commented on A Project Can Have Tasks

If I wanted to add an 'owner_id' value to the task is this the best way, i.e append the auth()->user()->id value to the data or is their a more graceful way using Eloquent?

    public function store(Project $project)
    {
        $attributes = $this->validateTask();

        $attributes['owner_id'] = auth()->user()->id;

        $project->addTask($attributes);

        return redirect($project->path());
    }

    public function validateTask()
    {
        return request()->validate([
            'body' => ['required', 'min:3']
        ]);
    }
Jun
25
4 months ago
Activity icon

Started a new Conversation UpdateExistingWithPivot

Is there a shorter way to do the following?

    public function updateProject($project)
    {
        Project::update($project);
        Project::find($this->id)->users()->updateExistingPivot(auth()->user(), ['role_id' => request('role_id')]);
    }

Is it really necessary to use two operations? On create I can use the following.

Project::create($attributes)->users()->attach(auth()->user(), ['role_id' => request('role_id')]);
Jun
22
4 months ago
Activity icon

Replied to User Relationships

I just stumbled upon a solution that works but I don't fully understand it so if anyone could give me some pointers or point me in the direction of some resource specifically related to this I would be grateful.

If I amend my ProjectUser class to the following:

class ProjectUser extends Pivot
{
    protected $appends = [
        'label',
    ];

    public function getLabelAttribute()
    {
        return $this->role;
    }

    public function role()
    {
        return $this->belongsTo(Role::class);
    }
}

All the fields from the Roles table become available in my Json, like this:

{  
   "id":1,
   "title":"My First Project",
   "description":"Vestibulum facilisis, purus nec pulvinar iaculis, ligula mi congue nunc, vitae euismod ligula urna in dolor. Praesent adipiscing. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Phasellus a est. Quisque libero metus, condimentum nec, tempor a, commodo mollis, magna.\r\n\r\nPellentesque posuere. Suspendisse non nisl sit amet velit hendrerit rutrum. Fusce risus nisl, viverra et, tempor et, pretium in, sapien. In auctor lobortis lacus. Vestibulum volutpat pretium libero.\r\n\r\nVivamus elementum semper nisi. Fusce fermentum odio nec arcu. Vestibulum fringilla pede sit amet augue. Donec id justo. Aliquam eu nunc.\r\n\r\nDonec interdum, metus et hendrerit aliquet, dolor diam sagittis ligula, eget egestas libero turpis vel mi. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur blandit mollis lacus. Vestibulum turpis sem, aliquet eget, lobortis pellentesque, rutrum eu, nisl. Proin faucibus arcu quis ante.\r\n\r\nIn ut quam vitae odio lacinia tincidunt. Maecenas ullamcorper, dui et placerat feugiat, eros pede varius nisi, condimentum viverra felis nunc et lorem. Proin magna. Vivamus consectetuer hendrerit lacus..",
   "created_at":"2019-06-17 21:23:12",
   "updated_at":"2019-06-17 21:23:12",
   "pivot":{  
      "user_id":1,
      "project_id":1,
      "role_id":1,
      "label":{  
         "id":1,
         "name":"Owner",
         "created_at":null,
         "updated_at":null
      },
      "role":{  
         "id":1,
         "name":"Owner",
         "created_at":null,
         "updated_at":null
      }
   }
},
Activity icon

Replied to User Relationships

Sorry, to re-open this but I have a related question.

With the above mentioned Eloquent model I can access the fields from my roles table using {{ $project->pivot->role->name }}, for example like this,

    @forelse ($projects as $project)
    <li>
        <a href="{{ $project->path() }}">{{ $project->title }} ({{ $project->pivot->role->name }})</a></li>
    </li>
    @endforelse

However, if I just return the data from the Eloquent model as a Json response in order to use it within a Vue component I can no longer access the fields from my roles table. The raw Json response looks like this,

{
"id": 1,
"title": "My First Project",
"description": "Vestibulum facilisis, purus nec pulvinar iaculis, ligula mi congue nunc, vitae euismod ligula urna in dolor. Praesent adipiscing. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Phasellus a est. Quisque libero metus, condimentum nec, tempor a, commodo mollis, magna.\r\n\r\nPellentesque posuere. Suspendisse non nisl sit amet velit hendrerit rutrum. Fusce risus nisl, viverra et, tempor et, pretium in, sapien. In auctor lobortis lacus. Vestibulum volutpat pretium libero.\r\n\r\nVivamus elementum semper nisi. Fusce fermentum odio nec arcu. Vestibulum fringilla pede sit amet augue. Donec id justo. Aliquam eu nunc.\r\n\r\nDonec interdum, metus et hendrerit aliquet, dolor diam sagittis ligula, eget egestas libero turpis vel mi. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Curabitur blandit mollis lacus. Vestibulum turpis sem, aliquet eget, lobortis pellentesque, rutrum eu, nisl. Proin faucibus arcu quis ante.\r\n\r\nIn ut quam vitae odio lacinia tincidunt. Maecenas ullamcorper, dui et placerat feugiat, eros pede varius nisi, condimentum viverra felis nunc et lorem. Proin magna. Vivamus consectetuer hendrerit lacus..",
"created_at": "2019-06-17 21:23:12",
"updated_at": "2019-06-17 21:23:12",
"pivot": {
"user_id": 1,
"project_id": 1,
"role_id": 1
}
},

So, as a result my roles fields are not available. Can anyone help me out here? Is it to do with eager loading?

Thanks

Jun
18
5 months ago
Activity icon

Replied to User Relationships

@davidpetrov - It seems to work well.

Test:

    public function a_user_can_create_a_project()
    {
        $this->actingAs(factory('App\User')->create());

        $this->get('/projects/create')->assertStatus(200);

        $role = factory('App\Role')->create();

        $attributes = [
            'title' => $this->faker->sentence,
            'description' => $this->faker->paragraph,
            'role_id' => $role->id,
        ];

        $this->post('/projects', $attributes)->assertRedirect('/projects');

        $this->assertDatabaseHas('projects', [
            'title' => $attributes['title'],
            'description' => $attributes['description'],
        ]);

        $this->get('/projects')->assertSee($attributes['title']);
    }

Controller:

    public function store(Request $request)
    {
        // validate
        $attributes = request()->validate([
            'title' => 'required',
            'description' => 'required',
        ]);

        // persist
        Project::create($attributes)->users()->attach(auth()->user(), ['role_id' => request('role_id')]);

        // redirect
        return redirect('/projects');
    }

    public function index()
    {
        $projects = auth()->user()->projects;

        return view('projects/index', compact('projects'));
    }

Model:

    public function projects()
    {
        return $this->belongsToMany(Project::class)->withPivot('role_id')->using(ProjectUser::class);
    }

I believe this, Project::create($attributes)->users()->attach(auth()->user(), ['role_id' => request('role_id')]);, is an efficient way to persist the record, I couldn't find any examples of making it shorter whilst still maintaining readability.

Jun
16
5 months ago
Activity icon

Replied to User Relationships

Thanks again. I have tidied up my migration example following your comments, does this look about right?

        Schema::create('users', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });

        Schema::create('projects', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('title');
            $table->text('description');
            $table->timestamps();
        });

        Schema::create('roles', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->timestamps();
        });

        Schema::create('project_user', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->unsignedBigInteger('project_id');
            $table->unsignedBigInteger('user_id');
            $table->unsignedBigInteger('role_id');
            $table->timestamps();

            $table->foreign('project_id')->references('id')->on('projects');
            $table->foreign('user_id')->references('id')->on('users');
            $table->foreign('role_id')->references('id')->on('roles');
        });
Activity icon

Replied to User Relationships

Thanks for your reply @davidpetrov. If you have some examples already that you can easily share then I would like to see them. The documentation is great, but some additional example would always be helpful at this stage.

Does this kind of idea and migration look like the right kind of direction?

users projects roles user_has_projects

        Schema::create('users', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });

        Schema::create('projects', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('title');
            $table->text('description');
            $table->timestamps();
        });

        Schema::create('roles', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->timestamps();
        });

    Schema::create('project_has_users', function (Blueprint $table) {
            $table->unsignedInteger('project_id');
            $table->unsignedInteger('user_id');
            $table->unsignedInteger('role_id');

            $table->foreign('project_id')
                ->references('id')
                ->on($tableNames['projects']);

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

            $table->foreign('role_id')
                ->references('id')
                ->on('roles');

            $table->primary(['user_id', 'project_id',  'role_id']);
        });
Activity icon

Started a new Conversation User Relationships

What would be the best way to construct my database tables to allow for the following relationships.

  • A project has an owner
  • A project has many collaborators
  • A collaborator can have different permission levels per project

Using Eloquent I would like to be able to show a single list of projects per user, for example:

USER A

  • Project 1 (Owner)
  • Project 2 (Owner)
  • Project 3 (Collaborator - Editor)
  • Project 4 (Collaborator - Read only)

Some questions:

  1. If I add a 'user_id' column in the projects table and a pivot table for 'many-to-many' relationships between users and projects will I easily be able to use an Eloquent query to display a single list of projects? I.e. because I will need to check both the user_id column in the projects table and the pivot table.
  2. Would it be better to use a single pivot table and assign a permission level as part of the pivot table, so on a relationship by relationship basis I could define the link between the user and the project and then somehow also add a permission type method?

I am new to Laravel, and just seeking clarification/advice on best practices for this kind of thing.

Thanks

Jun
08
5 months ago
Activity icon

Replied to Model Or Controller For Create, Update, Etc..

After further reading I have implemented this method.

Add a hasMany relationship to my User Model,

    public function projects()
    {
        return $this->hasMany(Project::class, 'owner_id');
    }

And then store a project like this,

    public function store()
    {

        $attributes = request()->validate([
            'title' => ['required', 'min:3'],
            'description' => ['required', 'min:3']
        ]);

        $project = auth()->user()->projects()->create($attributes);

        Mail::to('[email protected]')->send(
            new ProjectCreated($project)
        );

        return redirect('/projects');
    }

I am still a little unsure though whether this is correct? Is it generally preferred to use this eloquent create method to persist data in the database directly from within the Controller. I.e. rather than using a Project::create method in the Model?

Activity icon

Replied to Model Or Controller For Create, Update, Etc..

Thanks for the reply. Would it be possible to show me what you would do in this instance?

I have read that we should avoid using static functions, is this generally accepted?

Thanks

Jun
07
5 months ago
Activity icon

Started a new Conversation Model Or Controller For Create, Update, Etc..

Apologies, I am a beginner with Laravel. I am currently making my way through the fantastic 'Laravel 5.7 From Scratch' and have reached episode 28 where Jeffery creates a new email when adding a project.

His ProjectsController has this store method,

    public function store(Project $project)
    {

        $attributes = request()->validate(
             ['title' => ['required', 'min:3'], 'description' => ['required', 'min:3']]
        );

        $attributes['owner_id'] = auth()->id();

        $project = Project::create($attributes);

        return redirect('/projects');
    }

Which works fine. However, during one of the previous episodes Jeffery talked about how your database actions should live in the Model and not the Controller, well at least that was my understanding (but apologies if that is wrong).

He altered his update method to use this approach but not the store method so I had a go at this myself.

I have been using this in my Controller,

    public function store(Project $project)
    {

        $project->addProject(
            request()->validate(
                ['title' => ['required', 'min:3'], 'description' => ['required', 'min:3']]
            )
        );

        return redirect('/projects');
    }

And this in my Model,

    public function addProject($project)
    {
        Project::create($project + ['owner_id' => auth()->id()]);
    }

Which has been working fine. However, when I added the email function I found that I couldn't access the data from the newly created project in my email template. If I reverted to his store method it was fine so everything else was setup correctly.

I altered my method like this in the Controller,

    public function store(Project $project)
    {

        $project = $project->addProject(
            request()->validate(
                ['title' => ['required', 'min:3'], 'description' => ['required', 'min:3']]
            )
        );

        Mail::to('[email protected]')->send(
            new ProjectCreated($project)
        );

        return redirect('/projects');
    }

And this in the Model,

    public function addProject($project)
    {
        return Project::create($project + ['owner_id' => auth()->id()]);
    }

I.e I returned the data from the model and assigned it to a variable.

I am not sure if this is what I should be doing though? Should I be created my item in my Model, if so should I be returning the data back to my Controller like this or should I also be generating my email in the Model too? Or, should I do it all in the Controller like Jeffery?

Thanks for the advice!

Jun
03
5 months ago
Activity icon

Replied to Beginner Routes And Controllers Query

Hi. Thanks for all the advice and the link to the excellent presentation by Adam. I see how their isn't always one correct answer and it can depend on the particular project.

For now I am going to go with something like this,

Route::resource('projects', 'ProjectsController');
Route::post('/project-tasks/{project}', '[email protected]');
Route::patch('/project-tasks/{task}', '[email protected]');

More controllers and simple routes but I will keep an open mind whilst I am learning as their seems to be quite a few different considerations which need to be taking into account when trying to figure out the structure of the routes.

Jun
02
5 months ago
Activity icon

Started a new Conversation Beginner Routes And Controllers Query

I am new to Laravel so sorry if I have missed some obvious concepts with this question. I am working my way through 'Laravel 5.7 From Scratch' and am just seeking some clarification about route and controllers.

If I have a project where I know a joined item is going to be used widely throughout the database, i.e. Projects will have tasks, Clients will have tasks, Enquiries will have tasks etc... Should I use this approach to generate my web routes:

Route::resource('projects/{project}/tasks', 'ProjectTasksController');
Route::resource('clients/{client}/tasks', 'ClientTasksController');

Because if I try to shorten the URI, then I can do this for projects:

Route::resource('tasks', 'ProjectTasksController');

But then I am stuck, i.e. I cannot reuse the tasks route for client tasks because it has already been used.

If that above concept is correct in my ProjectTasksController I add:

use App\Task;
use App\Project;

And then in order to store or update a task which just has a description and a checkbox I do this,

    public function store(Project $project, Task $task)
    {
        $project->tasks()->create(request()->validate([
            'description' => ['required', 'min:3'],
        ]));

        return back();
    }

    public function update(Project $project, Task $task)
    {
        $task->update(request()->validate([
            'description' => ['required', 'min:3'],
            'completed' => ['boolean'],
        ]));

        return back();
    }

I have tried to follow the advice in the Laracasts and write my functions as succinctly as possible. Am I right to use (Project $project, Task $task) like that?

Sorry again if this is obvious to seasoned Laravel users, I am just trying to get to grips with the framework.

Thanks