I have the following relationships set up in Laravel:
OrderStatus Model
- hasMany('Order')
Order Model
- 'belongsTo('OrderStatus');
The database is set up with an orders
table and an order_statuses
table. The orders
table has a field for order_status_id
.
When I save an Order, I manually set the order_status_id
by fetching the appropriate Order Status model, like this:
$status = OrderStatus::where(['name'=>'sample_status'])->firstOrFail();
$order->order_status_id = $status->id;
$order->save();
I'm wondering if there is a built in function to do this rather than setting the order_status_id
manually. I've read about "Attaching a related model", and "Associating Models" in the Laravel docs, but I can't figure out if these fit my use case. I think the issue I'm having is that I'm working directly with the child model (the order), and trying to set it's parent. Is there a function for this?
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)
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
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.