2016-06-23 8 views
2

私は今数週間プロジェクトに取り組んできました。そのためにLaravelをピックアップしました(確かにファンです!)。 :すっきりしたルックアップテーブルとモデル作成

私は、ユーザーが提供する資格情報に基づいてさまざまなAPIにリクエストする必要があるアプリケーションを用意しています。これらのすべてのタスクは、同じサービスを提供することを目的としていますが、さまざまな方法で、オブジェクト指向のアプローチが良いと思うようになりました。私はストラテジーパターンとファクトリーパターンの両方を使っていくつかのアイデアを思いついたのですが、Eloquentのシンプルなレイアウトの次には魅惑的ではないようです。

私が言っていることのより良い例のように、ユーザー名、電子メール、または電話番号(選択したAPIの要件に応じて)を提供できるユーザーがいます。 api1_table: id, user_api_lookup_id, email

users: id, username, passhash

api_list: id, api_name, api_table_name, logo_url

user_api_lookup: id, user_id, api_list_id

が、これは私は何をするために右のセットアップのように見えるん:私は、これまでのようになりた4つのテーブルを作りました試して?

更新: 私はおそらく私のアプリケーションは、同様に

どのように見えるかを言及している必要があり、各ユーザーの多くのAPIの統合を持っており、

class User 
{ 
... 
    public function rewardMethods() 
    { 
     return $this->hasMany(APIIntegration::class); 
    } 
... 
} 

がうまくいけば、それは明確にこれらは雄弁の関係ヘルパーを使用してアクセスされていますビット

+0

APIには、*ユーザー名、メールアドレス、電話番号*のいずれかが必要です。あるいはそれ以上のものが必要なのでしょうか?この 'api1_table'は一つのAPIのためのもので、次のAPIは独自のデータベーステーブルを持っていますか? –

+0

これまでは、そのうちの1つを必要とするAPIのみを扱ってきました。 そして、それは私が 'apiN_table'のために考えていたものです –

+0

これは良いアプローチではありません、imho、mysqlのようなリレーショナルデータベースを使うとき。 –

答えて

1

これを最初にお読みください。

この例では、次のステートメントを前提としています

  • APIは、複数の資格情報を持つことができます。
  • ユーザーは複数のAPIを持つことができます。

これは、あなたがの関係をと1対1で対応することはできないということを意味しません。

私は、N個のAPIをサポートし、APIごとに別々のデータベーステーブルを持つことを避けるための良いアプローチの簡単な例を作成しました。

ここにデータベーステーブルがあります。

apisテーブルは、APIに関する情報を保持するapi_listと同等です。私の例では(私が言ったように、それは本当に簡単です)、私は列nameを追加しました。

CREATE TABLE `apis` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `name` varchar(255) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 

私はちょうどこの例では、単純なusers表を作っ:

CREATE TABLE `users` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `email` varchar(255) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 

その後、私は新しいテーブルを作ったが、APIが持つことができるすべてのクレデンシャルタイプを保持するどのcredentialsと呼ばれます。例:ユーザー名メール電話番号name列には、ユーザーフレンドリーな信任状の名前が入ります。

CREATE TABLE `credentials` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `name` varchar(255) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 

私は1つがcredentialを必要以上を持っているapisをカバーするアプローチを行ってきました。だから私はapiscredentialsの間のピボットテーブルが必要でした。私が必要

CREATE TABLE `api_credential` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `api_id` int(11) NOT NULL, 
    `credential_id` int(11) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 

次の表は、apiuserが持っているを保持するテーブルです。これは、user_api_lookupテーブルと同じです。

CREATE TABLE `api_user` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `api_id` int(11) NOT NULL, 
    `user_id` int(11) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 

そして最後の表は、実際の資格情報api_credential_user開催するものです。そして、私たちは(このためユーザーartisan少なくともI)を生成する必要があります

CREATE TABLE `api_credential_user` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `api_credential_id` int(11) NOT NULL, 
    `value` text NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 

私たちのモデルとそれらの間の関係を設定します。

php artisan make:model Api 
php artisan make:model ApiCredential 
php artisan make:model ApiCredentialUser 
php artisan make:model ApiUser 
php artisan make:model Credential 

UserモデルはLaravelのインストールが付属しています。

Apiモデルは次のようになります。 (私は各関係のコメントを追加しました)

class Api extends Model 
{ 
    protected $table = 'apis'; 

    /** 
    * As I said an API might have multiple credential types/fields. 
    */ 
    public function credentials() 
    { 
     return $this->belongsToMany('App\Credential'); 
    } 

    /** 
    * This will return all users that have a specific api attached. 
    */ 
    public function users() 
    { 
     return $this->belongsToMany('App\User'); 
    } 
} 

Credentialモデル:

class Credential extends Model 
{ 
    protected $table = 'credentials'; 

    /** 
    * Get all apis this credential belongs to. 
    */ 
    public function apis() 
    { 
     return $this->belongsToMany('App\Api'); 
    } 

    public function apiCredential() { 
     return $this->hasOne('App\ApiCredential'); 
    } 
} 

ApiCredentialモデル:

class ApiCredential extends Model 
{ 
    protected $table = 'api_credential'; 

    /** 
    * Those are defined in the sake of consistency. 
    * Probably will not be used. 
    */ 
    public function api() 
    { 
     return $this->belongsTo('App\Api'); 
    } 

    /** 
    * Those are defined in the sake of consistency. 
    * Probably will not be used. 
    */ 
    public function credential() 
    { 
     return $this->belongsTo('App\Credential'); 
    } 

    public function user() 
    { 
     return $this->hasOne('App\ApiCredentialUser'); 
    } 
} 

ApiCredentialUserモデル:

class ApiCredentialUser extends Model 
{ 
    protected $table = 'api_credential_user'; 
} 

Userモデル:デモの目的のために

class User extends Model 
{ 
    protected $table = 'users'; 

    public function apis() 
    { 
     return $this->belongsToMany('App\Api'); 
    } 
} 

ダミーデータ:これらの関係の

INSERT INTO `users` (`id`, `email`) VALUES (NULL, '[email protected]'), (NULL, '[email protected]'); 
INSERT INTO `credentials` (`id`, `name`) VALUES (NULL, 'phone_number'), (NULL, 'username'), (NULL, 'email'); 
INSERT INTO `apis` (`id`, `name`) VALUES (NULL, 'Github API'), (NULL, 'StackOverflow API'), (NULL, 'Twitter API'), (NULL, 'Facebook API'), (NULL, 'LinkedIn API'); 
INSERT INTO `api_credential` (`id`, `api_id`, `credential_id`) VALUES (NULL, '1', '1'), (NULL, '2', '2'),(NULL, '3', '3'), (NULL, '4', '1'),(NULL, '5', '2'); 
INSERT INTO `api_user` (`id`, `api_id`, `user_id`) VALUES (NULL, '1', '1'), (NULL, '2', '2'); 
INSERT INTO `api_credential_user` (`id`, `api_credential_id`, `value`) VALUES (NULL, '1', '0700-1111-2222'), (NULL, '2', 'myUsername'); 

サンプル用法:

Route::get('/test', function() { 
    //Fetching all users (dummy data) 
    $user_1 = App\User::find(1); 
    $user_2 = App\User::find(2); 

    //To list every user's apis 
    echo '<h3>User: ' . $user_1->email . '</h3>'; 
    echo 'Apis attached: <br />'; 
    echo '<ul>'; 
    foreach ($user_1->apis as $api) { 
     echo '<li>' . $api->name . '</li>'; 
     //You can get required credentials per api. 
     echo '<ul>'; 
     foreach ($api->credentials as $credential) { 
      //And for every credential you can get user's value. 
      echo '<li><b>Name:</b> ' . $credential->name . ' - <b>User value</b>: ' . $credential->apiCredential->user->value . '</li>'; 

     } 
     echo '</li></ul>'; 
    } 
    echo '</ul>'; 


    //To list every user's apis 
    echo '<h3>User: ' . $user_2->email . '</h3>'; 
    echo 'Apis attached: <br />'; 
    echo '<ul>'; 
    foreach ($user_2->apis as $api) { 
     echo '<li>' . $api->name . '</li>'; 
     //You can get required credentials per api. 
     echo '<ul>'; 
     foreach ($api->credentials as $credential) { 
      //And for every credential you can get user's value. 
      echo '<li><b>Name:</b> ' . $credential->name . ' - <b>User value</b>: ' . $credential->apiCredential->user->value . '</li>'; 
     } 
     echo '</li></ul>'; 
    } 
    echo '</ul>'; 

    //To list all apis 
    echo '<h3>All apis:</h3>'; 
    $apis = \App\Api::all(); 
    foreach ($apis as $api) { 
     echo $api->name . '<br />'; 
    } 

    //To list all credentials: 
    echo '<h3>All credentials:</h3>'; 
    $credentials = \App\Credential::all(); 
    foreach ($credentials as $credential) { 
     echo $credential->name . '<br />'; 
    } 
}); 

上記のダミーデータでは、screenshotとなります。

+0

この例を実装した後、私は少し混乱していましたが、それはそれを行うにはあまり良い方法ではないと言っているわけではありません。 代わりに私が雄弁に多型についてのいくつかのチュートリアルを見て、これらのリンクを発見した: https://laravel.com/docs/5.1/eloquent-relationships https://adamwathan.me/2015/09/03/プッシュ多形対データベース/ 私は先に進んできて、これまでかなりうまくいったものを使用しました –

+0

@AlexCあなたのことがうまくいくと思われる場合は、あなた自身で質問に答えてその答えを受け入れるべきです。 :) –

関連する問題