Laravel polymorphic relations: Passing model to controller

后端 未结 3 1096
自闭症患者
自闭症患者 2020-12-19 20:31

I want to use a single controller to save my comments for multiple models. So I created the CommentController, with the following store method:

public functi         


        
相关标签:
3条回答
  • 2020-12-19 20:57

    I implemented this way if you want, according to me it's the one of the bests way to do that.

    // Route::post('/comments/{model}/{id}', 'CommentController@store');
    class CommentController extends Controller {
    
    protected $model;
    
    public function __construct()
    {
        $this->model = Relation::getMorphedModel(
            request()->route()->parameter('model')
        );
    }
    
    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        dd($this->model); // return 'App\Post' or null
    }
    
    }
    
    0 讨论(0)
  • 2020-12-19 20:59

    Adam's solution is great, but I would not hard-code the model's namespace that way. Instead, what I would do is make use of Laravel's Relation::morphMap(), you can check it out here: https://laravel.com/docs/5.6/eloquent-relationships#polymorphic-relations

    That way, you will also make your database entries more readable. I recommend using a service provider to map the morphs.

    Also, the Model base class has a getMorphClass() method, so instead of $comment->commentable_type = 'App\\Models\\'.$model; I would use $comment->commentable_type = $model->getMorphClass();

    That way you integrate Laravel's logic into your code.

    0 讨论(0)
  • 2020-12-19 21:08

    Im not sure if this is the Laravel convension, but i have done the following:

    Made a route:

    Route::post('/Comment/{model}/{id}', [
        // etc
    ]);
    

    Then in the controller get the model and check against an array of allowed models, pass the id through and attach:

    public function store(Request $request, $model, $id) {
        $allowed = ['']; // list all models here
    
        if(!in_array($model, $allowed) {
            // return redirect back with error
        }
    
        $comment = new Comment();
        $comment->user_id = $request->user()->id;
        $comment->commentable_type = 'App\\Models\\'.$model;
        $comment->commentable_id = $id;
        $comment->body = $request->body;
        $comment->save();
    
        return redirect()->back();
    }
    

    Like I say, there is most likely a much better way to accomplish, but this is how I've done it. It keeps it short and sweet and checks if the model can take a comment.

    0 讨论(0)
提交回复
热议问题