I'm learning Laravel by creating a recipe website.
The idea is a user creates a recipe which includes a title, description and number of portions (and tags), and then is directed to a new view in which they add the ingredients.
I've got this working, and the user can successfully create the recipe and the ingredients, which are being written to their respective tables, but I'm unable to attach/sync them.
Relevant parts of the models:
Recipe Model:
class Recipe extends Model
{
public function ingredients(){
return $this->hasMany('App\Ingredient', 'recipe_ingredients');
}
}
Ingredient Model:
class Ingredient extends Model
{
public function recipe(){
return $this->belongsTo('App\Recipe', 'recipe_ingredients');
}
}
Ingredients Controller
public function store(Request $request)
{
$this->validate($request, [
'name' => 'required|max:255'
]);
$ingredient = new Ingredient;
$ingredient->name = $request->name;
$ingredient->save();
$recipe = Recipe::find($request->id);
$recipe->ingredients()->attach($recipe_id);
$data = [
'success' => true,
'message'=> 'Your AJAX processed correctly',
'name' => $ingredient->name,
'recipe' => $recipe
] ;
return response()->json($data);
}
If I remove the $recipe->ingredients()->attach($recipe_id);
the ingredients save to the ingredients table, but I can't get the recipe_id
and ingredient_id
to save in the recipe_ingredients
table`.
I think I'm using the attach wrong, but I could be wrong.
Note: Not that I think it makes any difference, but I'm submitting the data via Ajax.
Script:
$(document).ready(function(){
$("#submit").click(function() {
var name = $("#ingredientName").val();
var token = $("#token").val();
$.ajax({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
type: "post",
data: "name="+name,
dataType:'json',
url: "{{ route('ingredients.store', ['id' => $recipe->id]) }}",
success:function(data){
console.log(data);
$("#msg").html('<div class="alert alert-success my-0">'+data.name+' added</div>');
$("#msg").toggleClass("invisible")
$("#msg").fadeOut(2000);
$("#ingredientsTable").append('<tr><td scope="col" class="align-middle">'+data.name+'</td></tr>');
}
});
})
})
Revised Controller
public function store(Request $request)
{
$this->validate($request, [
'name' => 'required|max:255'
]);
$ingredient = new Ingredient;
$ingredient->name = $request->name;
$ingredient->save();
$recipe = Recipe::find($request->id);
$recipe->ingredients()->attach($ingredient->id);
$data = [
'success' => true,
'message'=> 'Your AJAX processed correctly',
'name' => $ingredient->name,
'recipe' => $recipe
] ;
return response()->json($data);
}
Table migration
public function up()
{
Schema::create('recipe_ingredients', function (Blueprint $table) {
$table->integer('recipe_id')->unsigned();
$table->foreign('recipe_id')->references('id')->on('recipes');
$table->integer('ingredient_id')->unsigned();
$table->foreign('ingredient_id')->references('id')->on('ingredients');
});
}