2016-11-16 5 views
1

ユーザーがサインアップするときに、注文(ユーザーセッションで保存されたID)を関連付けたいと思います。どこにLaravel Listenerロジックを置くか

Laravelサイトに記載されているイベントとリスナーを作成しました。私が抱えている問題は、レコードを関連付けるロジックがどこにあるのかわからないということです。最初はOrder Controllerに入れましたが、代わりにBuilder :: attachOrderToUserを参照しようとします。

私は私のモデルにメソッドを移動し、それは私がエラーを与えてる今が働いた:このロジックは、実際に行くべき場所

Call to undefined method Illuminate\Database\Query\Builder::attach()

は、誰かが指摘してもらえますか?

注文モデルのメソッド:ここ

/** 
* Attach Order to Customer 
* 
* @param int $id 
* @return \Illuminate\Http\Response 
*/ 
public static function attachOrderToUser($order_id, $user_id) 
{ 
    // @TODO: Wrap around event handler 
    $user = User::find($user_id); 

    if($user->order()->attach($order_id)) 
     return true; 
    else 
     return false; 

} 

は私のリスナーのコードです:

namespace App\Listeners; 

use App\Events\UserQuickSignUpComplete; 
use Illuminate\Queue\InteractsWithQueue; 
use Illuminate\Contracts\Queue\ShouldQueue; 

use Auth; 
use Session; 
use App\Order; 
use Illuminate\Http\Request; 

class AttachGuestOrderToUser 
{ 
    /** 
    * Create the event listener. 
    * 
    * @return void 
    */ 
    public function __construct() 
    { 
     // 
    } 

    /** 
    * Handle the event. 
    * 
    * @param UserQuickSignUpComplete $event 
    * @return void 
    */ 
    public function handle(UserQuickSignUpComplete $event) 
    { 
     // get currently logged in user (was signed in on method that triggers event) 
     $user = Auth::user(); 
     // get order 
     $order = Session::get('last_transaction.order_id'); 
     // attach order to user 
     Order::attachOrderToUser($order['order_id'], $user['id']); 
    } 
} 

他の提案もいただければ幸いです!

+1

なぜ間接ですか? 'handle'では' Auth :: user() - > order() - > attach(Session :: get( 'last_transaction.order_id')) 'を実行し、動作を確認する統合テストを行うことができます。 – bishop

+1

'$ user-> order()'の代わりに '$ user-> order'を試してください – mnv

+0

@bishopはロジックがハンドルにまっすぐ入るはずですか?これをコントローラまたはリポジトリに保存するのがベストプラクティスだと思いましたか? – Imran

答えて

1

2つのオブジェクトを結合すると、サービスと表示されます。そのようなサービスがどこに行くべきかは、問題です。コントローラーは、ユーザーの操作を制御していないため、正しくは感じません。リポジトリは、同じ種類のモデルのコレクションではなく2つの別々のモデルインスタンスを扱っているので、気分が悪いです。

しかし、イベントリスナーの名前を見てください:\App\Listeners\AttachGuestOrderToUser。それは特定の仕事を示唆する非常に特殊な名前です。私の考えでは、クラスはすでにサービスです。だから、私はそのリスナーに必要なロジックを置くだけです。

namespace App\Listeners; 

use App\Events\UserQuickSignUpComplete; 

class AttachGuestOrderToUser 
{ 
    /** 
    * You guessed it: attach a guest order to a specific user. 
    * 
    * @param UserQuickSignUpComplete $event 
    * @return void 
    */ 
    public function handle(UserQuickSignUpComplete $event) 
    { 
     \Auth::user()->order()->attach(\Session::get('last_transaction.order_id')); 
    } 
} 

一般に、イベントリスナーは特定の種類のサービスなので、将来のコードリーダーにとっては直感的に理解できます。

+0

ロジックがリスナーハンドルにあるので、どのようにphpunitでこれをテストしますか? – Imran

+0

@Imran 'new AttachGuestOrderToUser'、テストデータで' handle'を呼び出し、 '\ Auth'でユーザ呼び出しを疑似させます。 – bishop

関連する問題