Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

PHP

Laravel - What's the the best way to scope todo lists and todo items to a user?

I'm not sure if there's a specific term for what I'm trying to do - I think in the Ruby on Rails ODOT course it was referred to as "scoping to the user".

I think I would describe this kind of application as a 'multiple tennancy' application? I.e. each user has access to only their own todo lists and todo items, but shouldn't be able to access another users stuff.

Things I've done so far:

  • Upon creation of a todo list, todo_list.user_id field is populated with the logged in user_id.
  • The lists on the "todos" page are only those belonging to that user.
  • Only logged in users can access the application

What I'm trying to do

When I login as user1, I can still access the todo lists of user2 via the url.

Say todo-list-1 belongs to user1 and todo-list-2 belongs to user2.

If i login as user2 I can still go to (and edit!) a user1 todo list. www.laravel-basics.dev:8000/todos/1/edit

I have done a bit of reading around this, and have worked out a couple of ways to resolve this. I'm trying to pick the best option in terms of DRY and expandability.

Filters & Routes

http://laravel.com/docs/routing#route-filters I've looked into making a filter group similar to that where checking for logged in/logged out status (here follows a very rough example!)

<?php

//routes.php
Route::group(array('before' => 'author_only'), function () { ... }
<?php

//filters.php
Route::filter('author_only',function()
{
$user = Sentry::getUser();
if ($user->id != $list->user_id){
  return Redirect::to('/');
} 
});

This is probably the route (weyhey!) I would take were I just creating todo_lists. But it could potentially require more work for list_items? (a model which is still specific to a user, but separated by an additional JOIN... Having said that the todo_list id is passed into the routes for list items, but adding all this logic to the route/filter seems a little messy.)

Query Scoping

http://laravel.com/docs/eloquent#query-scopes An alternative method is to creat query scopes inside each model. Again, this is quite simple and would work for both todo lists and todo items. My query (weyhey!) with this is - my need to 'scope' to a user is relatively global. It's pretty much throughout the entire application.

Oh wait.

Global Scopes

http://laravel.com/docs/eloquent#global-scopes

With an opening line of

Sometimes you may wish to define a scope that applies to all queries performed on a model.

this sounds pretty good. But I would still have to repeat these steps for each model related to the user? What if I add more user specific models to the application - I would have to create a new global scope every time? This seems more manageable but also seems like I'll be repeating myself.

Multiple Tenancy

http://culttt.com/2014/03/31/multi-tenancy-laravel-4/

I found the above tutorial from culttt.com, which I think describes pretty much all of what I want to do. Great.

But scrolling down to the first code block, they've created an interface called Context. It uses 'use Illuminate\Database\Eloquent\Model'.

I simply don't know where to place this file! They also use serviceProviders (which I think are also referred to as 'services'?). I've looked through quite a bit of the documentation and narrowed it down to this page. I think this might be what I need to do, but don't really know where to start implementing. While I understand the documentation, I'm stumped as to what I can actually do with it.

I can solve my problem with the first few methods I mentioned. But I want to solve my problem in the best way possible! If any of the Laravel Legends out there could point me in the right direction with good words to google or give me a hand implementing, that would be incredibly helpful!

I'm working out of the 'users' branch if you want to take a look on github