Code Monkey home page Code Monkey logo

landlord's Introduction

Landlord for Laravel & Lumen 5.2+

Landlord for Laravel & Lumen 5.2+

StyleCI Status
Build Status

A single database multi-tenancy package for Laravel & Lumen 5.2+.

Upgrading from Landlord v1? Make sure to read the change log to see what needs updating.

Installation

To get started, require this package:

composer require hipsterjazzbo/landlord

Laravel

Add the ServiceProvider in config/app.php:

    'providers' => [
        ...
        HipsterJazzbo\Landlord\LandlordServiceProvider::class,
    ],

Register the Facade if you’d like:

    'aliases' => [
        ...
        'Landlord'   => HipsterJazzbo\Landlord\Facades\Landlord::class,
    ],

You could also publish the config file:

php artisan vendor:publish --provider="HipsterJazzbo\Landlord\LandlordServiceProvider"

and set your default_tenant_columns setting, if you have an app-wide default. LandLord will use this setting to scope models that don’t have a $tenantColumns property set.

Lumen

You'll need to set the service provider in your bootstrap/app.php:

$app->register(HipsterJazzbo\Landlord\LandlordServiceProvider::class);

And make sure you've un-commented $app->withEloquent().

Usage

This package assumes that you have at least one column on all of your Tenant scoped tables that references which tenant each row belongs to.

For example, you might have a companies table, and a bunch of other tables that have a company_id column.

Adding and Removing Tenants

IMPORTANT NOTE: Landlord is stateless. This means that when you call addTenant(), it will only scope the current request.

Make sure that you are adding your tenants in such a way that it happens on every request, and before you need Models scoped, like in a middleware or as part of a stateless authentication method like OAuth.

You can tell Landlord to automatically scope by a given Tenant by calling addTenant(), either from the Landlord facade, or by injecting an instance of TenantManager().

You can pass in either a tenant column and id:

Landlord::addTenant('tenant_id', 1);

Or an instance of a Tenant model:

$tenant = Tenant::find(1);

Landlord::addTenant($tenant);

If you pass a Model instance, Landlord will use Eloquent’s getForeignKey() method to decide the tenant column name.

You can add as many tenants as you need to, however Landlord will only allow one of each type of tenant at a time.

To remove a tenant and stop scoping by it, simply call removeTenant():

Landlord::removeTenant('tenant_id');

// Or you can again pass a Model instance:
$tenant = Tenant::find(1);

Landlord::removeTenant($tenant);

You can also check whether Landlord currently is scoping by a given tenant:

// As you would expect by now, $tenant can be either a string column name or a Model instance
Landlord::hasTenant($tenant);

And if for some reason you need to, you can retrieve Landlord's tenants:

// $tenants is a Laravel Collection object, in the format 'tenant_id' => 1
$tenants = Landlord::getTenants();

Setting up your Models

To set up a model to be scoped automatically, simply use the BelongsToTenants trait:

use Illuminate\Database\Eloquent\Model;
use HipsterJazzbo\Landlord\BelongsToTenants;

class ExampleModel extends Model
{
    use BelongsToTenants;
}

If you’d like to override the tenants that apply to a particular model, you can set the $tenantColumns property:

use Illuminate\Database\Eloquent\Model;
use HipsterJazzbo\Landlord\BelongsToTenants;

class ExampleModel extends Model
{
    use BelongsToTenants;
    
    public $tenantColumns = ['tenant_id'];
}

Creating new Tenant scoped Models

When you create a new instance of a Model which uses BelongsToTenants, Landlord will automatically add any applicable Tenant ids, if they are not already set:

// 'tenant_id' will automatically be set by Landlord
$model = ExampleModel::create(['name' => 'whatever']);

Querying Tenant scoped Models

After you've added tenants, all queries against a Model which uses BelongsToTenant will be scoped automatically:

// This will only include Models belonging to the current tenant(s)
ExampleModel::all();

// This will fail with a ModelNotFoundForTenantException if it belongs to the wrong tenant
ExampleModel::find(2);

Note: When you are developing a multi tenanted application, it can be confusing sometimes why you keep getting ModelNotFound exceptions for rows that DO exist, because they belong to the wrong tenant.

Landlord will catch those exceptions, and re-throw them as ModelNotFoundForTenantException, to help you out :)

If you need to query across all tenants, you can use allTenants():

// Will include results from ALL tenants, just for this query
ExampleModel::allTenants()->get()

Under the hood, Landlord uses Laravel's anonymous global scopes. This means that if you are scoping by multiple tenants simultaneously, and you want to exclude one of the for a single query, you can do so:

// Will not scope by 'tenant_id', but will continue to scope by any other tenants that have been set
ExampleModel::withoutGlobalScope('tenant_id')->get();

Contributing

If you find an issue, or have a better way to do something, feel free to open an issue or a pull request.

landlord's People

Contributors

bissolli avatar christian-thomas avatar geomagilles avatar grahamcampbell avatar jbrooksuk avatar luizreginaldo avatar omranic avatar phaberest avatar renanwilliam avatar rikvdlooi avatar tonydew avatar torkiljohnsen avatar vernesto84 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

landlord's Issues

Polymorphism

Hi guys,

Please, can you tell me how to make the scope of my queries with the package using polymorphism relationship?

Like how to set the type (tenant class) and the id (tenant id).

Thanks in advance!

Nested Resources don't seem to work

I have nested resources for Account -> has many Templates
I added Landlord to my Account controller and when I checked the DB log, I see the tenant condition added. When I did the same for the Template Controller, I don't see a check when I find the account. Here is my show code

    public function show($account_id, $template_id)
    {
        DB::enableQueryLog();
        $account = Account::findOrFail($account_id);
        DB::disableQueryLog();
        dd(DB::getQueryLog());

It returns

array:1 [
0 => array:3 [
"query" => "select * from accounts where accounts.id = ? limit 1"
"bindings" => array:1 []
"time" => 0.85
]
]

My middleware that I confirmed is being passed through is the following

            $tenantId = Auth::user()->id;
            Landlord::addTenant('user_id', $tenantId);

Why would it work in my AccountController but not in my TemplateController. The only difference I see is the nesting.

Can i replace the tenant id ?

In my application, i have a permissions called "elevate-tenant" that allows an user to select any tenant from the system to be associated with the registry. This permission is usually applied on admin roles.

If i call addTenant() from a middleware, i will get to replace the tenant calling addTenant() again or it will create another tenant ?

Laravel 5.3

Hi.

Just started using your package, and I really enjoy it so far!

Since Laravel 5.3 is being released soon (and I'm building a application), I tried to use landlord on the newest beta. However this package is dependent on 5.2.*, and therefore fails to install.
What's the current plan (and potential hurdles) we'll have to overcome to make this compatible with laravel 5.3?

(I have tried to make a local fork and have successfully installed Landlord on 5.3 (by changing the composer.json), but I haven't been able to test the functionality further. I will report back when I get to it.)

Implicit Binding

This is a great product.
But I don't think that this works with Implicit Binding. For eg

Doesn't work
public function show(Lead $lead)
{
return $lead;
}

This works:
public function show($id)
{
return Lead::find($id);
}

Kindly check

Error basic usage - Can only flip STRING and INTEGER values

I'm using laravel 5.3 :

ErrorException in Arr.php line 351:
array_flip(): Can only flip STRING and INTEGER values!

in Arr.php line 351
at HandleExceptions->handleError('2', 'array_flip(): Can only flip STRING and INTEGER values!', 'C:\wamp\www\still-reaches-22650\vendor\laravel\framework\src\Illuminate\Support\Arr.php', '351', array('array' => array('account_id' => '1'), 'keys' => array(null)))
at array_flip(array(null)) in Arr.php line 351
at Arr::only(array('account_id' => '1'), array(null)) in Collection.php line 652
at Collection->only(null) in TenantManager.php line 177
at TenantManager->modelTenants(object(Client)) in TenantManager.php line 106
at TenantManager->applyTenantScopes(object(Client)) in BelongsToTenants.php line 29
at Client::bootBelongsToTenants()
at forward_static_call(array('App\Client', 'bootBelongsToTenants')) in Model.php line 330
at Model::bootTraits() in Model.php line 316
at Model::boot() in Model.php line 303
at Model->bootIfNotBooted() in Model.php line 284
at Model->__construct() in Model.php line 647
at Model::all() in HomeController.php line 35
at HomeController->index()

... and so on

Scope not being applied

I installed and configured Landlord, and created a route to test if it was working. The use case is very simple: I have a User model and an Account model, where a User can have multiple Accounts. The Accounts table has a "user_id", and the Eloquent relationship is defined in both models as well.

// app/Http/routes.php
Route::get('test/{id}', function($id) {
    Landlord::addTenant('user_id', $id);

    return view('test')->with('accounts', App\Account::all());
});
// app/Account.php

namespace App;

use Illuminate\Database\Eloquent\Model;
use HipsterJazzbo\Landlord\BelongsToTenant;

class Account extends Model
{
    use BelongsToTenant;

    ...
}

When I access that route, I'm still getting the accounts for all the users. Debugbar shows the SQL query:

select * from `accounts`

Any ideas on what's missing?

Multiple tenants of the same type

Hi,

The idea is the following. A Teacher model can belong to multiple Schools at the same time.

Having school_id on the teachers table will not be enough.

Is it possible to support storing tenant values in a pivot table ?

Many-to-many?

Could it be nice to also have a trait that supports many-to-many relation between tenant and another resource?

For instance if a have a table of features and each tenant can activate/deactivate that feature? Pivot table would hold feature_id and tenant_id for instance.

Would be nice when getting a list of features that these are automatically scoped by tenant by a trait, say BelongsToManyTenants perhaps?

… or is this better solved in some other way I have not thought of?

Landlord enabled/disabled variables are private instead of protected.

I'd like to create my own scope based off of the Landlord scope.

Unfortunately, it seems that enabled and disabled are private so I can't bail out of apply early.

The reason I'd like this functionality is I have a scenario where I'd like optional tenant scoping on a table. I.e. there are roles in system that are shared globally (basically presets), and then there are roles that are tied to specific tenants. Roles that are shared globally do not have a tenant_id but they're on the same table.

Question

attention: stupid question department
newbie wants to know if he should even attempt to use package with cakephp3 ?
ie. any advice or docs to assist

model tenant_column variable.

only scoped model with respect to what column will be specified on model.

protected $tenant_column = ['company_id'];

What is the purpose of the config file?

In the documentation it says I can set a site wide default tenant column but the app/landlord.php file doesn't seem to do anything.

'default_tenant_columns' => ['tenant_id'],

I still have to specify the $tenantColumn in my middleware or anywhere else I want to use it.

public function handle($request, Closure $next)
{
    $tenantColumn = 'tenant_id';
    $tenantId = '1';

    Landlord::addTenant($tenantColumn, $tenantId);

    return $next($request);
}

Doesn't even work.

I have a Role model. I've publish the config file, set the model to use the trait, and also made sure that tenant_id exists in the roles table. I've also called Landlord::addTenant('tenant_id', $tenant->id); in my group middleware.

When I dump getTenants() on the page I get:

Illuminate\Support\Collection Object ( [items:protected] => Array ( [tenant_id] => 1 ) )

Well when I run this simple code:

        $roles = Role::all();

        foreach ($roles as $role) {
            echo $role->name.'<br>';
        }

It is echoing the roles that belong to any tenant. This does not even work at all.

Example App Please

It would be really great to see a small example application for this project to better understand how to implement it the right way, thank you very much!

change readme

The trait to use in models is BelongsToTenant, not BelongsToTenants like in readme

BelongsToTenant not working on user model

Hey Guys,

everything works fine: If I query with Model::find(123) on my model and the resource does not belong to the current tenant (set via middleware) the request fails.

But: If I query on the User model it does not work. While asking for User::all() I get really all results including other customers and while querying User::findOrFail() with an ID which does not belong to the current tenant I get the result .. so everytime working with my user model I have to check if $model->tenant_id == $request->user()->tenant_id

Issue on tests

I'm trying to test features that use Landlord but the scope is not applied unless I call $landlord->applyTenantScopes(new Model); manually before query.

Simple failed test example:

/** @test **/
function scopeTest()
{
    $user = User::create([
        'name' => 'User name',
        'email' =>'test@domain',
        'password' => bcrypt('secret'),
        'remember_token' => str_random(10),
    ]);

    Landlord::addTenant($user);

    Account::create([
        'name' => 'Account name',
        'user_id' => $user->id,
    ]);

    Account::create([
        'name' => 'Account name',
    ]);

    $count = Account::count();

    $this->assertEquals(1, $count);
}

I can fix easy the test calling applyTenantScopes() but I can't fix real tests that are using controllers, repositories...

Scope Not being applied in middleware

I added a ScopeRequestByUser middleware like so

public function handle($request, Closure $next)
{

    if ($request->ajax() || $request->wantsJson()) {
        Landlord::addTenant('user_id', Auth::guard('api')->id());
    }

    return $next($request);
}

Now this works perfectly when I add this to my global middleware stack like this.

protected $middleware = [
    \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
    \App\Http\Middleware\ScopeRequestByUser::class,
];

However, I need it to be applied only on the api middleware group. When I add to the group in the middleware file it does not work.

    protected $middlewareGroups = [
        'web' => [
          ...
        ],

        'api' => [
            'throttle:60,1',
            'bindings',
            \App\Http\Middleware\ScopeRequestByUser::class,
        ],
    ];

I even tried adding it ot the route middleware and then calling it both in the routes file and in the api middleware group. Both of them are not working.

    protected $routeMiddleware = [
        ...
        'scope' => \App\Http\Middleware\ScopeRequestByUser::class,
    ];

Not sure, what is going wrong here.

Eloquent ORM

Great work on Landlord, however, it does not seem to work with ORM relationships.

My member model has a tenant column called site_id. I have a another model called Profile that has a relationship to Member, but no site_id.

I'm calling Landlord::addTenant('site_id', $data['siteId']) in my middleware.

class Member extends Model
{
    use BelongsToTenant;
}

class Profile extends Model
{
    public function member()
    {
        return $this->hasOne('Models\Member');
    }
}

If I tried to find a record using a profile id, the Landlord tenant code does not protect the reference to member.

$profile = Profile::find(1)

$profile->member  // returns the member record regardless of the tenant column set.

Am I missing something or is there a way to address this?

Support for Lumen?

Any plan to support for Lumen?

I just made a few change at the LandlordServiceProvider.php, but I do not know if this is the lumen way or not.. Seems it works for me...

Here is what I've done so far:

<?php

namespace HipsterJazzbo\Landlord;

use HipsterJazzbo\Landlord\Facades\LandlordFacade;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Foundation\Application as LaravelApplication;
use Illuminate\Foundation\AliasLoader;
use Illuminate\Support\ServiceProvider;
use Laravel\Lumen\Application as LumenApplication;

class LandlordServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap the application events.
     *
     * @return void
     */
    public function boot()
    {
        // setup config
        $source = realpath(__DIR__ . '/../config/landlord.php');

        if ($this->app instanceof LaravelApplication && $this->app->runningInConsole()) {
            $this->publishes([$source => config_path('landlord.php')]);
        } elseif ($this->app instanceof LumenApplication) {
            $this->app->configure('landlord');
        }
    }

    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        $this->app->singleton(Landlord::class, function () {
            return new Landlord();
        });

        // Define alias 'Landlord'
        if ($this->app instanceof LaravelApplication && $this->app->runningInConsole()) {
            $this->app->booting(function () {
                $loader = AliasLoader::getInstance();

                $loader->alias('Landlord', LandlordFacade::class);
            });
        }
    }
}

Is it possible to throw ModelNotFoundForTenantException with firstOrFail

I ran into a route model binding issue with my Tenant Middleware so I decided to forego that. I'm also using a Sluggable package and don't want my URLs to show the index value. I tried firstOrFail with a slug condition but it simply returned a ModelNotFoundException.

Is there any way to make this work beyond doing an extra query to look up the ID based on slug?

Implicit Model Biding with LandLord

Hey guys!

I started using implicit model binding and LandLord isn't working anymore! I think it is happening because when the model binding do their job I didn't set LandLord tenant yet! Somebody know any trick to do that?

There is how my code works now:

  • My base controller:
public function __construct()
    {
        $this->middleware('auth:tenant');
        $this->middleware(function ($request, $next) {
            LandLord::addTenant('tenant_id', auth()->user()->tenant_id);
            return $next($request);
        });
    }
  • Method Example
public function show(Lead $lead)
    {
        try {
            // It gives the result without filtering my Tenant! 
            // So I can access any tenant's lead!
            return $lead;
        } catch (\Exception $e) {
            return response($e->getMessage(), $e->getCode() || 500);
        }
    }

Multiple Tenant Columns, Disable Just One?

My setup has 2 different tenant columns: site_id and season_id. For the large majority of things I want both of them. However there are a few queries where I actually want to ignore the season_id tenant while still keeping the site_id. Is there an easy way to do that that I'm just not seeing?

It looks like I might be able to pull it off but it would involve globally removing it, doing the query, and then globally adding it back in as soon as it's done. That's just not pretty.

No tenantId

I added Landlord::addTenant($tenantColumn, $tenantId) to the Authenticate middleware, since I wanted this on every authenticated page.

I get: Undefined variable: tenantColumn

Scope is not applied in middleware (TenantManager::tenants array is always empty)

I'm not sure if I've made a mistake in the set up of my application, but it doesn't apply the scope when I call Landlord::addTenant() in middleware, whereas if I hardcode it in the routes file, it applies it.

It seems that this is because all the models using the BelongsToTenants trait have already been instantiated before the middleware is run, so that when TenantManager::applyTenantScopes() calls the modelTenants() method, the tenants array is always empty.

AFAIK this was not an issue in v1.

I'd be grateful of any help!

Edit: my current workaround is calling bootBelongsToTenants() on the model again after addTenant():
Landlord::addTenant('company_id', $company->id);
\App\Models\Site::bootBelongsToTenants();

TenantModelNotFoundException incompatible declaration of setModel

Receiving the following error:

Declaration of HipsterJazzbo\Landlord\Exceptions\TenantModelNotFoundException::setModel() should be compatible with Illuminate\Database\Eloquent\ModelNotFoundException::setModel($model, $ids = Array)

Using Laravel 5.3.19 on PHP 7.0.6

Tenant ID column is ignored when updating a model

It seems like the tenant id column is ignored when updating a model, it only goes by the ID of the model.
Is there any way to make it update WHERE tenant_id = x as well?

This is a real issue for me when I use multi tenant (1 db) and also have "grouped" tables, example below.


system_id id
1 1
1 2
2 1

Does anyone have a work around for this problem?

Regards,
Daniel

5.1 Compatibility?

Since 5.1 is the Long-Term Support version of Laravel, I'm wondering if it would be appropriate to support that as well? What features have been included in 5.2 that aren't in 5.1?

This is a very important concern for LTS-only organizations who don't want to upgrade Laravel every 6-12 months.

Where to run addTenant

The documentation does not make it quite clear where you would put the call to Landlord::addTenant(), althought I assume in some sort of middleware, however It would be great if a couple of examples of real world usage would be placed in the docs.

Any plans for Lumen 5.4 ?

Hi !

How are you ? Hope you are fine !

It appears that we cannot upgrade to Lumen 5.4 because of Landlord's "illuminate/support 5.2.*" dependecy.. Any plans for supporting Lumen 5.4 ?

Thank you

Non-static method HipsterJazzbo\Landlord\Landlord::addTenant

Hi, I'm having this error:
'Non-static method HipsterJazzbo\Landlord\Landlord::addTenant() should not be called statically, assuming $this from incompatible context'...

When I try to put that line in a middleware

Landlord::addTenant('com_id', 2);

Modify tenant id in after middleware?

Hey,

It seems like it's not possible to modify the Tenant ID after it's been set once.

Currently we're setting in a Scope Middleware, that's globally applied, and it works perfectly.

But we have a few instances where we'd like to change/modify the Tenant ID to be something else, if we need to run artisan commands or other console related commands.

This is what i've tested with:

`\DB::enableQueryLog();

    User::whereActivated(1)->get();
    $this->info(json_encode(\Landlord::getTenants()));

    
    \Landlord::disable();
    User::whereActivated(1)->get();
    $this->info(json_encode(\Landlord::getTenants()));
    
    
    \Landlord::removeTenant('company_id');
    User::whereActivated(1)->get();
    $this->info(json_encode(\Landlord::getTenants()));
    
    
    \Landlord::addTenant('company_id',123);
    User::whereActivated(1)->get();
    $this->info(json_encode(\Landlord::getTenants()));
    
    \Landlord::addTenant('company_id',123);
    User::allTenants()->whereActivated(1)->get();
    $this->info(json_encode(\Landlord::getTenants()));
    
    dd( \DB::getQueryLog() );`

And this is the response i'm getting:

{"company_id":71}
{"company_id":71}
[]
{"company_id":123}
{"company_id":123}
array:5 [
0 => array:3 [
"query" => "select * from users where activated = ? and users.company_id = ? and users.deleted_at is null"
"bindings" => array:2 [
0 => 1
1 => 71
]
"time" => 0.72
]
1 => array:3 [
"query" => "select * from users where activated = ? and users.company_id = ? and users.deleted_at is null"
"bindings" => array:2 [
0 => 1
1 => 71
]
"time" => 0.82
]
2 => array:3 [
"query" => "select * from users where activated = ? and users.company_id = ? and users.deleted_at is null"
"bindings" => array:2 [
0 => 1
1 => 71
]
"time" => 0.44
]
3 => array:3 [
"query" => "select * from users where activated = ? and users.company_id = ? and users.deleted_at is null"
"bindings" => array:2 [
0 => 1
1 => 71
]
"time" => 0.49
]
4 => array:3 [
"query" => "select * from users where activated = ? and users.deleted_at is null"
"bindings" => array:1 [
0 => 1
]
"time" => 0.42
]
]

As seen, the Tenant ID is the same for all of them, except after i've called "allTenants()", it correctly removed the tenant-scope, but that's not what i want to achieve.

Is this an issue with this package, or something deeper in Eloquent's way of handling the global scopes?

In addition to this, Disable() does not seem to make any difference at all either.

Documentation error

There is a documentation error. Docs say to use "use HipsterJazzbo\LaravelMultiTenant\Traits\BelongsToTenant;" but it returns error because directory doesn't exist. Correct usage based on current directory is "use HipsterJazzbo\Landlord\BelongsToTenant;"

Hostname based ?

Hi, I was wondering of it possible to use tenant_id based on hostname from a table. Can this package auto detect the hostname? I am terribly in need of this package and will need a quick ans if possible. Thanks in advance 👍

Validation rules not being scoped

Hi!
Just like the tittle says, validation rules are not being scoped.
This results in errors when, for example, a unique rule is applied and there is already a same value from another Tenant.

Does Landlord support Laravel's Route Model Binding?

Hello,
I just started using Landlord for a new project and things were going well until I started using Laravel's route model binding. When using route model binding I have any record returned whether part of the tenant's records or not when using route model binding. If I simply pass the id into the function and perform my own findOrFail($id) then everything works as it should and trying to access those records not part of the tenant's fail. I have a middleware class that sets the tenant applied on the Route::group as only some of my routes need multi-tenant support.

My guess is that I'm implementing something incorrectly, but I'd like to know if this is a workable configuration or I simply can't used route model binding.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.