I've looked at a few similar issues on SO, but I can't work out why recipes is being called?
I'm building a recipes website, and the user can create tags, create a recipe, create ingredients which are assigned to the recipe, and will be able to create steps which use the ingredients.
The following are my models:
Ingredient.php
class Ingredient extends Model
{
protected $touches = ['recipes'];
public function recipes(){
return $this->belongsToMany('App\Recipe', 'recipe_ingredients', 'ingredient_id', 'recipe_id');
}
public function step(){
return $this->belongsToMany('App\Step', 'step_ingredients');
}
}
Recipe.php
class Recipe extends Model
{
public function ingredients(){
return $this->belongsToMany ('App\Ingredient', 'recipe_ingredients', 'recipe_id', 'ingredient_id');
}
public function tags(){
return $this->belongsToMany('App\Tag', 'recipe_tag');
}
public function user(){
return $this->belongsTo('App\User');
}
public function steps(){
return $this->hasMany('App\Step');
}
}
Step.php
class Step extends Model
{
protected $touches = ['recipes'];
public function recipe(){
return $this->belongsTo('App\Recipe');
}
public function ingredient(){
return $this->belongsToMany('App\Ingredient', 'step_ingredient');
}
}
The following is my StepsController which I'm saving to from my steps/create.blade.php file via an Ajax submit with jQuery.
use Illuminate\Http\Request;
//use Session;
use App\Recipe;
use App\Tag;
use App\Step;
use App\Ingredient;
class StepsController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function create($recipe_id)
{
$recipe = Recipe::find($recipe_id);
return view('steps.create')->withRecipe($recipe);
}
public function store(Request $request)
{
$step = new Step;
$step->recipe_id = 2;
$step->step_no = 2;
$step->is_prep = 1;
$step->duration = '00:14:01';
$step->method = 'test';
$step->save();
$data = [
'success' => true,
'message'=> 'Your AJAX processed correctly',
'ing' => json_decode($request->ingredients),
'desc' => $request->description
] ;
return response()->json($data);
}
}
I'm using static values for the new Step to make sure that it writes to the db correctly, and it is.
If I comment out writing the step to the db, and just leave the $data array and return response... then it works fine, and I get the success response returned to the view.
When I include it, I get the error in the console:
[Error] Failed to load resource: the server responded with a status of 500 (Internal Server Error) (steps, line 0)
"message": "Method Illuminate\\Database\\Query\\Builder::recipes does not exist.",
But I'm not sure where the recipes method is being called?! I think it has something to do with my relationships in the model?
Any insight would be extremely appreciated.
Not sure if it's required, but the following is the part of my script that I"m using so submit data with Ajax.
$("#addStepNew").click(function() {
var step_ingredients = JSON.stringify(stepIngredients)
var step_description = $('#stepDescription').val();
// var prep_step = $('input[name=prepStep]:checked').val();
$.ajax({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
type: "post",
data: {ingredients: step_ingredients, description: step_description},
dataType:'json',
url: "{{ route('steps.store', ['id' => $recipe->id]) }}",
success: function (data) {
$("#ajaxOutput").html('<code>Description output: '+data.desc+'</code>');
$.each(data.ing, function (key, value) {
$("#ajaxOutput").append('<br><code>'+value.ingredient_name+'</code>');
});
},
error: function (xhr, ajaxOptions, thrownError) {
console.warn(xhr.responseText);
alert(xhr.status);
alert(thrownError);
}
});
});
It looks like it's the protected $touches = ['recipes']; from the Step model.
I guess it's trying to update a recipe that it's associated to, but that isn't being defined with a recipe_id.
Related
Is there the possibility to get whole database's table with it's associates?
My example
class Gambler extends Model
{
use HasFactory;
public function horse()
{
return $this->belongsTo(Horse::class, 'horse_id', 'id');
}
}
I am fetching data of Gamblers with axios, which is being returned with this code in controller
public function getGamblers () {
echo Gambler::all();
}
However I would like to get all associated Horses as well. I can get one pretty easy just like this
public function getGamblers () {
echo Gambler::find(1)->horse;
}
but maybe there is possibility to do something like this, which in my case does not work
public function getGamblers () {
echo Gambler::all()->horse;
}
You should use return in Controllers, not echo.
Because you are using axios, a JsonResponse will be more appropriate:
public function getGamblers () {
return response()->json(Gambler::all(), 200);
}
Gambler::all() will return a Collection of Gambler.
On frontend, loop over the data you get from Laravel:
let gamblers = [];
axios.get('/your-get-gamblers-url')
.then(function (response) {
gamblers = response.data;
})
gamblers.forEach(gambler => console.log(gambler))
If for some reson you need to do something with each Gambler in php, you can loop over the collection like this:
$gamblers = Gambler::all()
foreach($gamblers as $gambler) {
//$gambler->horse
}
I want to show pivot data into json format
I have 2 relationship many to many mode: SubmitForm and Fisherman.
// submitform model
public function fisherman()
{
return $this->belongsToMany(Fisherman::class, 'submitform_fisherman','submitform_id', 'fisherman_id');
}
// fisherman model
public function submitForm()
{
return $this->belongsToMany(SubmitForm::class,'submitform_fisherman','fisherman_id', 'submitform_id');
}
this is my submitformcontroller to show the data
use App\Http\Resources\SubmitformResource;
use App\SubmitForm;
class SubmitFormController extends Controller
{
public function index()
{
return SubmitformResource::collection(SubmitForm::with('fisherman')->get());
}
....
}
this is my SubmitformResource
class SubmitformResource extends JsonResource
{
public function toArray($request){
return [
"id" => $this->id,
"product_form" => $this->product_form,
"fisherman" => $this->whenPivotLoaded('submitform_fisherman', function(){
return new FishermanResource($this->pivot->fisherman);
})
}
}
when I tried i dont get fisherman data.
Can someone help me?
I need the delete query within this controller
public function del($id)
{
$x=App\ImageMod::find();
// $x->where("id='$id'");
$x->delete();
return view('show');
}
How can I fetch the id dynamically and delete it?
you can delete for eg blog in this way:
public function destroy($id)
{
$blog = Blog::findOrFail($id);
$blog->delete();
return redirect()->back()->with('success','Blog deleted');
}
Use the Request dependency injection. Then, get the id property from your route. Then you can access the id from the request. Your code would looks like:
Controller
public function del(Request $request) {
$id = $request->id;
$x=App\ImageMod::destroy($id);
return view('show');
}
And then in routes/web.php you should have:
Route::delete('imagemod/delete/{id}', 'App\YourController#delete')->name('imagemod.delete');
Pass the $id from your page (ajax or even a direct request) by placing it within the route. If using ajax, something like:
$.ajax({ url: "{{url('ImageMod')}}/" + id, // <-- id from an input, pulling the val()
type: "DELETE",
data: {
_method: 'DELETE'
},
success: function (success) { .. }
In your web.php:
Route::delete('ImageMod/{id}', 'ImageModController#destroy');
Then, the routing binds that variable to the destroy method:
public function destroy($id)
{
ImageMod::destroy($id);
return 1; // if going back to ajax
}
You can also use:
public function destroy($id)
{
DB::table('blogs')->where('id', '=', $id)->delete();
}
4 and have a problem with ajax request.
It's my JS:
$.ajax({
url: 'get-map',
type: 'POST',
dataType: 'json'
});
web.php:
Route::group(['middleware' => 'auth'], function () {
Route::post('/create-character', 'MainController#createCharacter');
Route::get('/main', 'MainController#main');
Route::group(['middleware' => 'check.character.exist'], function() {
Route::get('/game', 'GameController#index');
Route::post('/get-map', 'MapController#getMapForCharacter');
});
});
__construct in MapController.php:
class MapController extends Controller {
private $mapFieldId;
public function __construct()
{
parent::__construct();
$character = Character::find($this->characterId);
$this->mapFieldId = $character->map_field_id;
}
}
and __construct in Controller.php:
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
protected $userId;
protected $characterId;
public function __construct()
{
$this->middleware(function ($request, $next) {
if (Auth::id()) {
$this->userId = Auth::id();
$character = Character::where('user_id', '=', $this->userId)->first();
if ($character) {
$this->characterId = $character->id;
}
}
return $next($request);
});
}
}
Works correctly in HTTP request but ajax return: ErrorException in MapController.php line 18: Trying to get property of non-object
$character = Character::find($this->characterId);
During investigate I discover that middleware in Controller.php doesn't start - parser just skip it (only for ajax request).
And i have no idea why.
Any suggestion?
I try to do ajax using angularjs but I get 500 internal server error in console.
angular
$scope.submit = function(){
$http.post('shop', {'order_list': JSON.stringify($scope.order_list)})
.success(function(data) {
console.log(data);
});
}
Laravel's Controller
public function addtocart(){
OrderList::unguard();
$order_list_input = json_decode(Input::get('order_list'));
$order_list = new OrderList;
$order_list->order_id =1;
$order_list->product_id = $order_list_input->product_id;
$order_list->amount = $order_list_input->amount;
$order_list->total_cost = Prod::find($order_list_input->product_id)->price * $order_list_input->amount;
$order_list->save(); //works when I comment this line out.
var_dump($order_list_input);
}
I don't get it. I just comment out that line and it works.
Laravel's Model
class OrderList extends Eloquent
{
protected $table = 'order_lists';
protected $fillable = array('order_id','product_id','amount','total_cost');
public function order_list_attribute() {
return $this->hasMany('Order_list_attribute');
}
public function product(){
return $this->hasOne('Prod');
}
}
Thank's for your help :D