can't access variable in view from controller laravel - php

I can't access $prospectus in the function show() but works well in the function store() in laravel version 5.6.27
public function store(Request $request) {
$course = Course::create([
'name' => $request['name'],
'title' => $request['title'],
'division_id' => $request['division_id'],
]);
$prospectus = Prospectus::create([
'years' => $request['years'],
'name' => $course->name,
'user_id' => null,
'course_id' => $course->id,
]);
return view('courses.show', compact('course', 'prospectus'));
}
public function show(Course $course) {
$prospectus = Prospectus::where('course_id', $course->id)->get();
//return $prospectus;
return view('courses.show', compact('course', 'prospectus'));
}
the data is passed when i use return $prospectus; but not in return view('courses.show', compact('course', 'prospectus'));
here are my routes
Route::resource('courses', 'CourseController');
Route::post('courses', 'CourseController#store')->name('courses.store');
Route::get('courses/{course}', 'CourseController#show')->name('courses.show');

I supose you want a single Prospectus object, get() will give you a collection of objects.
Use the first() function to get only the first match from the database as a single object.
$prospectus = Prospectus::where('course_id', $course->id)->first();

Confirm that $prospectus query don't return NULL
Try this:
$prospectus = Prospectus::where('course_id', $course->id)->first();

Related

Hi i get this "Error Call to a member function update() on boolean" when updating image in Laravel

Can someone help me with this Laravel problem?
I get Error Call to a member function update() on boolean, when I edit and update Image for an ad.
So when I create a new Ad the image will store but when updating the Ad with a new image the old image stays and I get this error for this line in storeImage.
private function storeImage($ad){
if (request()->has('image')) {
$ad->update([
'image' => request()->image->store('uploads', 'public'),
]);
$image = Image::make(public_path('storage/' . $ad->image))->fit(300, 300, null, 'top-left');
$image->save();
}
}
This is my AdsController
public function edit($id)
{
$ad = Ad::find($id);
return view('ads.edit_ad', compact('ad', 'id'));
}
public function update(Request $request, $id)
{
$ad = Ad::find($id);
$user_id = Auth::user()->id;
$rules = [
'ad_title' => 'required',
'ad_description' => 'required',
'purpose' => 'required',
'image' => 'sometimes|file|image|max:5000',
];
$this->validate($request, $rules);
$title = $request->ad_title;
$is_negotialble = $request->negotiable ? $request->negotiable : 0;
$data = [
'title' => $request->ad_title,
'description' => $request->ad_description,
'type' => $request->type,
'price' => $request->price,
'purpose' => $request->purpose,
'address' => $request->address,
'user_id' => $user_id,
];
$updated_ad = $ad->update($data);
if ($updated_ad){
$this->storeImage($updated_ad);
}
return redirect()->back()->with('success','Ad Updated');
}
public function destroy(Ad $ad)
{
$ad->delete();
return redirect()->back()->with('success','Ad Deleted');
}
/**
* Listing
*/
public function listing(Request $request){
$ads = Ad::all();
$roles = Role::all();
return view('listing', compact('ads'));
}
public function myAds(){
$user = Auth::user();
$ads = $user->ads()->orderBy('id', 'desc')->paginate(20);
return view('ads.my_ads', compact('ads'));
}
private function storeImage($ad){
if (request()->has('image')) {
$ad->update([
'image' => request()->image->store('uploads', 'public'),
]);
$image = Image::make(public_path('storage/' . $ad->image))->fit(300, 300, null, 'top-left');
$image->save();
}
}
At the bottom of your update() function, try to change this:
if ($updated_ad){
$this->storeImage($updated_ad);
}
to this:
if ($updated_ad){
$this->storeImage($ad);
}
The Eloquent models update() function returns a boolean of whether the update completed successfully. After running the update() function on the $ad variable, it is mutated and contains the updated data, and you can use it as an argument in your storeImage() function.

How to call two models in the same function using Laravel?

I have two functions in my controller, I would like to call the model Tbl_Perimetro and Tbl_Holding, I've achieved to call Tbl_Perimetro.. but I don't know how to call Tbl_Holding to work in the same way of Tbl_Perimetro
these are my functions
public function edit($id)
{
if(request()->ajax())
{
$data = Tbl_Perimetro::findOrFail($id);
return response()->json(['result' => $data]);
}
}
public function update(Request $request, Tbl_Perimetro $user)
{
$rules = array(
'rif' => 'required',
'razon_social' => 'required',
'holdings_id' => 'required',
'pines_id' => 'required'
);
$error = Validator::make($request->all(), $rules);
if($error->fails())
{
return response()->json(['errors' => $error->errors()->all()]);
}
$form_data = array(
'rif' => $request->rif,
'razon_social' => $request->razon_social,
'holdings_id' => $request->holdings_id,
'pines_id' => $request->pines_id
);
Tbl_Perimetro::whereId($request->hidden_id)->update($form_data);
return response()->json(['success' => 'Datos actualizados satisfactoriamente.']);
}
You don't need to use Tbl_Perimetro $user in your update() function's argument.
Instead, include the Models at the beginning of your controller:
use App\Tbl_Perimetro;
use App\Tbl_Holding;
And then you can use those models anywhere in that controller:
Tbl_Perimetro::whereId($request->hidden_id)->update($form_data);
Tbl_Holding::whereId($request->hidden_id)->update($form_data);
Hope it helps.
Do like this:
$data1=tbl_Perimerto::findorfail($id1);
$data2=tbl_Holding::findorfail($id2);
return reponse()->json( ['result1'=>$data1,'result2'=>$data2]);
But what is $id1 and $id2? They was passed from routing:
route::get('/yoururl/{id1}/{id2},['uses'=>'YourController#method']);
and in your controllers method you should get them in arguement like this:
public function method($id1,$id2)

Laravel API Resource not returning correct value with condition

I am new to Laravel API, I want to return a book where recommended === 1
In my resources, I have this
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'about' => $this->about,
'content' => $this->content,
// 'image' => asset('/storage/'.$this->image),
'image' => $this->image_url,
// 'recommended' => $this->recommended,
'recommended' => $this->when($this->recommended === 1, $this->recommended),
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
'author' => $this->author,
];
I want to return books when recommended === 1
My table is Like this
public function up()
{
Schema::create('books', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->text('about');
$table->string('image');
$table->string('image_url');
$table->string('epub_url');
$table->integer('author_id');
$table->string('publisher');
$table->year('year');
$table->boolean('recommended')->default(0);
$table->timestamps();
});
I was able to achieve the same thing on web using this
public function index()
{
$data = array();
$data['recommends'] = Book::where('recommended', 1)->take(10)->get();
$data['latests'] = Book::orderBy('created_at', 'desc')->take(10)->get();
return view('welcome', compact("data"));
}
But I don't know how to replicate the same using Laravel API.
UPDATE
I was able to achieve the same thing on web using this
public function index()
{
$data = array();
$data['recommends'] = Book::where('recommended', 1)->take(10)->get();
$data['latests'] = Book::orderBy('created_at', 'desc')->take(10)->get();
return view('welcome', compact("data"));
}
But I don't know how to replicate the same using Laravel API.
Normally I will get all Books or Post like this using API Resource
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'about' => $this->about,
'content' => $this->content,
'image' => $this->image_url,
'recommended' => $this->recommended,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
'author' => $this->author,
];
and call it like this in my controller
public function indexapi()
{
return BookResource::collection(Book::with('author')->Paginate(16));
}
But there some cases recommended is == 1 and some recommended == 0, in this case, I want to return data only when recommended == 1
I know my question is quite confusing
Thanks.
Thanks.
If I get it right, you want to filter & get only the books with ( recommended attribute == 1 ). If thats the case you shouldn't do it in your Collection file. You should do this filtering process in your Controller before passing any data to Collection.
Here is some code example from one of my project.
In ProductController.php FILE
public function index()
{
return new ProductCollection( Product::where('recommended','1')->get() );
}
As you can see , I'm filtering the products to get only the recommended ones. Then I'm sending this filtered data to the ProductCollection. This way The collection will only return the data I want.
In ProductCollection.php FILE
public function toArray($request)
{
return [
'data' => $this->collection->map( function($data) {
return [
'id' => (integer) $data->id,
'name' => $data->name,
'category_id' => $data->category_id,
'brand_id' => $data->brand_id,
'photos' => json_decode($data->photos),
'gtin' => $data->gtin
];
})
];
}
I don't have to make any changes in Collection. Because in this way , Collection should do the job for every data it gets.

Laravel - adding relationships to a factory-created model

I am testing an eager loading relationship which contains many to many relations. Right now I have the queries and attachments within the test. I'm wondering if there is a way to move them into the factory, rather than including it as part of your test. This would limit the size of the test and then these relations could be created and used every time a film factory is created.
test
public function grabFilmTest()
{
$film = factory(Film::class)->create();
$categories = Category::where('main-cat', 'Science')->where('sub-cat', 'Fiction')->first();
$languages = Languages::where('name', 'english')->first();
$film->categories()->attach($categories->id);
$film->languages()->attach($languages->id);
$response = $this->json('GET', '/film/' . $film->id)
->assertStatus(200);
$response
->assertExactJson([
'id' => $film->id,
'name' => $film->name,
'description' => $film->description,
'categories' => $film->categories->toArray(),
'languages' => $film->languages->toArray()
}
filmFactory
$factory->define(\App\Models\Film::class, function (Faker $faker){
return [
'id' => $faker->uuid,
'name' => $faker->text,
'description' => $faker->paragraph,
];
});
If anyone could help with how i could do this or an example it would be great :D
You could use factory states and factory callbacks.
$factory->define(\App\Models\Film::class, function (Faker $faker){
return [
'id' => $faker->uuid,
'name' => $faker->text,
'description' => $faker->paragraph,
];
});
$factory->define(\App\Models\Category::class, function (Faker $faker){
return [
// Category fields
];
});
$factory->define(\App\Models\Language::class, function (Faker $faker){
return [
// Language fields
];
});
$factory->afterCreatingState(\App\Models\Film::class, 'with-category', function (\App\Models\Film $film) {
$category = factory(\App\Models\Category::class)->create();
$film->categories()->attach($category->id);
});
$factory->afterCreatingState(\App\Models\Film::class, 'with-language', function (\App\Models\Film $film) {
$language = factory(\App\Models\Language::class)->create();
$film->categories()->attach($language->id);
});
Then you can use in tests like this:
public function grabFilmTest()
{
$film = factory(Film::class)->create();
$filmWithCategory = factory(Film::class)->state('with-category')->create();
$filmWithLanguage = factory(Film::class)->state('with-language')->create();
$filmWithCategoryAnLanguage = factory(Film::class)->states(['with-category', 'with-language'])->create();
// ...
}
PS: I don't recommend using existing data. From experience, I can tell you that can become really painful.
You can use factory callbacks to do it in the factory file:
<?php
use \App\Models\Film;
use \App\Models\Category;
use \App\Models\Languages;
$factory->define(Film::class, function(Faker $faker){
return [
'id' => $faker->uuid,
'name' => $faker->text,
'description' => $faker->paragraph,
];
});
$factory->afterCreating(Film::class, function(Film $film, Faker $faker) {
$category = Category::where('main-cat', 'Science')->where('sub-cat', 'Fiction')->first();
$language = Languages::where('name', 'english')->first();
$film->categories()->attach($category);
$film->languages()->attach($language);
});

FatalThrowableError Call to a member function where() on null for laravel 5.5 API request

Hi I am trying to build the API from laravel. I am using eloquent resources to manage API. I get FatalThrowableError Call to a member function where() on null when passing id that do not exist in database.
Routes :
Route::resource('hotel', 'HotelController',['only'=>['index','show']]);
Resource :
public function toArray($request)
{
return [
'id' => $this->hotel_id,
'name' => $this->name,
'summary' => $this->summary,
'description' => $this->description,
'contactno' => $this->contactno,
'address' => $this->address,
'latitude' => $this->latitude,
'longitude' => $this->longitude,
'star' => $this->star,
'image' => base_resource_url().$this->image,
'facilities' => $this->facility,
];
}
}
Controller :
public function show($id)
{
return new HotelResource(Hotel::find($id)->where(['suspend'=>1,'verify'=>1])->first());
}
When I pass the ID that is present in database I can get the json data but when I pass the ID that is not present in database in show($id) method of controller then I get FatalThrowableError Call to a member function where() on null how can I handle this exception in laravel to throw some readable json error response like :
{error : not data found with accosiated ID}
You need to check that the record exists first. For example:
public function show($id)
{
if ($hotel = Hotel::find($id)) {
// hotel exists
}
abort(404, 'Hotel does not exist');
}
Update
Hotel::find($id) will only return 1 or 0 records. Applying the where clauses followed by first() doesn't make sense.
// is this what you mean?
Hotel::where(['id' => $id, 'suspend' => 1, 'verify' => 1])->first()
Update 2
public function show($id)
{
if ($hotel = Hotel::where(['id' => $id, 'suspend' => 1, 'verify' => 1])->first()) {
return new HotelResource($hotel);
}
abort(404, 'Hotel does not exist');;
}

Categories