Laravel save one to many relationship

后端 未结 3 1247
陌清茗
陌清茗 2021-02-19 14:14

I have the following relationships set up in Laravel:

OrderStatus Model
  - hasMany(\'Order\')

 Order Model
  - \'belongsTo(\'OrderStatus\');

相关标签:
3条回答
  • 2021-02-19 14:29

    You can go with a custom solution.

    I am explaining an example, just coded and very much similar to your question, hope it will help. I have a Question Model and AnswerOption Model as below.

    Question Model

    namespace App\Models;
    
    use Illuminate\Database\Eloquent\Model;
    
    class Question extends Model
    {
        protected $table = 'questions';
        protected $fillable =  [
            'title',
            'created_at',
            'updated_at'            
        ];
    
    
        /**
         * Get the answer options for the question.
         */
        public function answerOptions()
        {
            return $this->hasMany('App\Models\AnswerOption');
        }
    
    
        /**
         * @param array $answerOptions
         */
        public function syncAnswerOptions(array $answerOptions)
        {
            $children = $this->answerOptions;
            $answerOptions = collect($answerOptions);        
            $deleted_ids = $children->filter(
                function ($child) use ($answerOptions) {
                    return empty(
                        $answerOptions->where('id', $child->id)->first()
                    );
                }
            )->map(function ($child) {
                    $id = $child->id;
                    $child->delete();                
                    return $id;
                }
            );        
            $attachments = $answerOptions->filter(
                function ($answerOption) {
                     // Old entry (you can add your custom code here)
                    return empty($answerOption['id']);
                }
            )->map(function ($answerOption) use ($deleted_ids) {
                    // New entry (you can add your custom code here)           
                    $answerOption['id'] = $deleted_ids->pop();                
                    return new AnswerOption($answerOption);
            });        
            $this->answerOptions()->saveMany($attachments);
        }   
    }
    

    AnswerOption Model

    namespace App\Models;
    use Illuminate\Database\Eloquent\Model;
    
    class AnswerOption extends Model
    {
        protected $table = 'answer_options';
    
        protected $fillable =  [
            'question_id',
            'title',
            'ord',
            'created_at',
            'updated_at'            
        ];      
    
        /**
         * Get the question that owns the answer.
         */
        public function question()
        {
            return $this->belongsTo('App\Models\Question');
        }   
    }
    

    Here you can see a single question hasMany answer options, you can see I have used BelongsTo , hasMany relationsip in models.

    Now in QuestionController during Question save and update, you can also save the answer options.

    For this I have written syncAnswerOptions method in Question Model.

    You just need to pass the array of options with id, if id is present already in the database then it will update, if id is blank it will add a new record, If Id was there but not in your new array, then that record will get deleted.

    /**
     * If you are attaching AnswerOption(s) for the first time, then pass
     * in just the array of attributes:
     * [
     *     [
     *         // answer option attributes...
     *     ],
     *     [
     *         // answer option attributes...
     *     ],
     * ]
     *//**
     * If you are attaching new AnswerOption(s) along with existing
     * options, then you need to pass the `id` attribute as well.
     * [
     *     [
     *         'id' => 24
     *     ],
     *     [
     *         // new answer option attributes...
     *     ],
     * ]
     */
    

    In Question controller's store and update method call this method just after question add and update call.

    $question->syncAnswerOptions($data['answerOptions']);
    

    $data['answerOptions'] is Array of answer options just like described in the comments.

    0 讨论(0)
  • 2021-02-19 14:33

    Sure you can do this:

    $status = OrderStatus::where(['name'=>'sample_status'])->firstOrFail();
    $order = new Order;
    $order->status()->associate($status);
    $order->save();
    

    (status() is the belongsTo relation. You might need to adjust that name)

    0 讨论(0)
  • 2021-02-19 14:36

    The correct way, to save a relationship for a new related model is as follows:

    $status = OrderStatus::where(['name'=>'sample_status'])->firstOrFail();
    $order = new Order;
    $status->order()->save($order);
    

    Documentation link : http://laravel.com/docs/4.2/eloquent#inserting-related-models

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