Reputation: 7692
I've two tables to save data to. One of them has foreign key so that I have one-to-many relationship. However, I don't understand how to save data into two table simultaneously. I have one query which contains data for one table and for another that should be attached to first one.
That is the main model
class Site extends Model
{
protected $fillable = ['path', 'site_link'];
public $timestamps = false;
public function features() {
return $this->hasMany('App\SiteFeature');
}
}
And this is the sub-model
class SiteFeature extends Model
{
protected $fillable = ['feature', 'site_id'];
public $timestamps = false;
}
Right now my controller looks like this
class SiteController extends BaseController
{
public function index()
{
return Site::all();
}
public function show(Site $id)
{
return $this->response->item($id, new SiteTransformer);
}
public function store(Request $request)
{
$site = Site::create($request->all());
return response()->json($site, 201);
}
I know that it would save it as one piece of data. And I ask you for help me to split data into two tables. In docs I've found the way to store with relationship to an existing model in DB, however I don't have that model at the moment of creation.
Upvotes: 5
Views: 9287
Reputation: 440
It's the correct way to save data using hasMany relationship without creating a new object of lookup model.
// inside controller
public function store(Request $request)
{
$student = Student::create([
"name" => $request->get('name'),
"email" => $request->get('email'),
]);
foreach ($request->subjects as $subject) {
$student->subjects()->create(["title" => $subject['title']);
}
return response()->json($student, 201);
}
// inside User model
public function subjects()
{
return $this->hasMany('App\Models\Subject');
}
Upvotes: 1
Reputation: 7692
Solved that way
public function store(Request $request)
{
$site = Site::create([
"path" => $request->path,
"site_link" => $request->link,
]);
foreach ($request->features as $feature) {
$site->features()->save(new SiteFeature(["feature" => $feature]));
}
return response()->json($site, 201);
}
Upvotes: 7
Reputation: 117
There are certain things you have to make sure of.
First: In your SiteFeature
-Model the inverse relation to the Site
-Models seems to be missing.
There should be a function like:
public function site()
{
return $this->belongsTo('App\Site');
}
See Laravel 5.6 - Eloquent Relationships, One-to-Many for this.
If however you have a relationship where (n) Sites can be related to (n) SiteFeatures, your relations and inverse relations have to be different. (And there will also have to be a pivot table, in which you can store the n-to-n relation)
See Laravel 5.6 - Eloquent Relationships, Many-to-Many in that case.
Since your Question does not describe what is received with $request, here's what you should consider:
First step:
$site = Site::firstOrCreate(['path' => $request['input_name_for_path'],
'site_link' => $request['input_name_for_site_link'],
]);
This will give you a proper Site
-Model saved to the database.
(Note, that this shows how you manually assign values to the fillable fields defined in the model in case you have different input field names)
Now you can go on an save the SiteFeature
-Model connected to it:
$feature = SiteFeature::firstOrCreate('feature' => $request['input_name_for_feature');
$site->features()->attach($feature->id);
This should do the trick saving both, a new (or old) Site
and a related SiteFeature
to your database.
If I misunderstood the question, feel free to add information and I will update.
Upvotes: 0