Php Laravel保存一对多关系

Php Laravel保存一对多关系,php,laravel,laravel-4,eloquent,Php,Laravel,Laravel 4,Eloquent,我在Laravel建立了以下关系: OrderStatus Model - hasMany('Order') Order Model - 'belongsTo('OrderStatus'); 数据库设置有一个订单表和一个订单状态表。orders表中有一个用于order\u status\u id的字段 当我保存订单时,我通过获取适当的订单状态模型手动设置订单状态\u id,如下所示: $status = OrderStatus::where(['name'=>'sample_

我在Laravel建立了以下关系:

OrderStatus Model
  - hasMany('Order')

 Order Model
  - 'belongsTo('OrderStatus');
数据库设置有一个
订单
表和一个
订单状态
表。
orders
表中有一个用于
order\u status\u id
的字段

当我保存订单时,我通过获取适当的订单状态模型手动设置
订单状态\u id
,如下所示:

$status = OrderStatus::where(['name'=>'sample_status'])->firstOrFail();
$order->order_status_id = $status->id;
$order->save();
我想知道是否有一个内置函数来完成这项工作,而不是手动设置
order\u status\u id
。我在Laravel文档中读过“附加相关模型”和“关联模型”,但我不知道这些是否适合我的用例。我认为我遇到的问题是,我直接处理子模型(顺序),并试图设置它的父模型。是否有此功能?

确定您可以执行此操作:

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

status()
是belongsTo关系。您可能需要调整该名称)

为新的相关模型保存关系的正确方法如下:

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

文档链接:

您可以使用自定义解决方案

我正在解释一个例子,刚刚编码,非常类似于你的问题,希望它能有所帮助。 我有一个问题模型回答选项模型,如下所示

问题模型

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);
    }   
}
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');
    }   
}
应答器选项型号

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);
    }   
}
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');
    }   
}
在这里你可以看到一个问题有很多答案选项,你可以看到我用了BelongsTo,在模型中有很多关系

现在,在问题保存和更新期间,您可以在QuestionController中保存答案选项

为此,我在问题模型中编写了syncAnswerOptions方法

您只需要传递id为的选项数组,如果id已存在于数据库中,则它将更新;如果id为空,则它将添加一条新记录;如果id存在但不在新数组中,则该记录将被删除

/**
 * 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...
 *     ],
 * ]
 */
问题控制器的存储和更新方法在问题添加和更新调用之后调用此方法

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

$data['answerOptions']是一组答案选项,就像评论中描述的那样。

Oh哇哦,看起来这很管用。我的问题是我没有在
associate()
之后调用
save()
。因此,
associate()
只需更新
$order
上的
order\u status\u id
字段的值,但实际上并不涉及数据库?它就是这样做的:)