How model relationships works with blades? - laravel

I have a model 'applicants' and it has a 'belongsTo' relationship with 'BloodGroup' model.
Here is the index function from ApplicantController:
public function index()
{
$user = Auth::user();
// $user = User::find(1);
$applicants = $user->applicants->where('visible', 1);
foreach ($applicants as $applicant) {
$applicant->bloodGroup;
$applicant->fiqa;
$applicant->gender;
}
// return response()->json($applicants);
return view('applicants.index', ['applicants' => $applicants]);
}
Here is the response that I get from the API:
{
"1": {
"id": 4,
"blood_group_id": 1,
"created_at": "2019-04-22 13:24:16",
"updated_at": "2019-04-26 10:21:41",
"blood_group": {
"id": 1,
"name": "A+",
"visible": 1,
"created_at": "2019-04-22 08:21:19",
"updated_at": "2019-04-22 08:21:19"
}
}
}
But when I pass data to the view. It generates an error in the following lines:
<div class="row mx-4">
<div class="col-06 pr-3">
<p class="h5">Name:</p>
</div>
<div class="col-06">
<p><?php echo e($applicant->blood_group->name); ?></p>
</div>
</div>
BloodGroup Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class BloodGroup extends Model
{
public function applicants()
{
return $this->hasMany('App\Applicant');
}
}
BloodGroup relationship in Applicants table:
public function bloodGroup()
{
return $this->belongsTo('App\BloodGroup');
}
Can you please point out what I'm doing wrong and how this should be done.

As your relationship suggests
public function bloodGroup()
{
return $this->belongsTo('App\BloodGroup');
}
for a particular applicant, $applicant = Applicant::find(1);, you will be able to get bloodGroup like $applicant->bloodGroup, now you should be able to get the name with $applicant->bloodGroup->name.
Your code should be
public function index()
{
$user = Auth::user();
$applicants = $user->applicants()->where('visible', 1)->get();
return view('applicants.index', ['applicants' => $applicants]);
}
In your view
#foreach ( $applicants as $applicant )
{{ $applicant->bloodGroup->name }}
#endforeach
#swonder's concern
>>> App\User::find(1)->roles->where('role_id', '<', 1)
=> Illuminate\Database\Eloquent\Collection {#3178
all: [
App\models\Role {#3166
id: 1,
name: "super-admin",
display_name: "Super Admin",
description: "This will be one permission, that can not be assigned or
modified.",
created_at: "2019-01-11 19:06:23",
updated_at: "2019-01-11 19:06:23",
pivot: Illuminate\Database\Eloquent\Relations\Pivot {#3141
user_id: 1,
role_id: 1,
},
},
],
}
yes #swonder is correct, you should use
$user->applicants()->where('visible', 1)->get();
and not $user->applicants->where('visible', 1) instead you may try collection where with all() or get(), but you may not prefer that after looking into below observation
>>> App\User::find(1)->roles->where('role_id', '=', 1)
=> Illuminate\Database\Eloquent\Collection {#3160
all: [],
}
>>> App\User::find(1)->roles->whereStrict('role_id', '=', 1)
=> Illuminate\Database\Eloquent\Collection {#3163
all: [],
}
>>> App\User::find(1)->roles->whereStrict('role_id', '<', 1)
=> Illuminate\Database\Eloquent\Collection {#3169
all: [],
}
>>> App\User::find(1)->roles->whereStrict('role_id', '>', 1)->all()
=> []
>>> App\User::find(1)->roles->whereStrict('role_id', '>', 1)->all()
>>> App\User::find(1)->roles->whereStrict('role_id', '=', 1)->all()
=> []
>>> App\User::find(1)->roles->whereStrict('role_id', '>', 1)->all()
=> []

What is the error that it says?
return view('applicants.index', ['applicants' => $applicants]);
You are passing applicants to the view but you use $applicant in it. Are you looping over $applicants? If no that's the error.

I'm finding issue with your code, since you're running a query but not actually asking anything out of it here:
$applicants = $user->applicants()->where('visible', 1);
This will need to be come:
$applicants = $user->applicants()->where('visible', 1)->get();
Since you're calling them anyway, perhaps try eager loading the relationships with:
$applicants = $user->applicants()->with('blood_group')->where('visible', 1)->get();
Resulting in your index method to look like this:
public function index()
{
$user = Auth::user();
$applicants = $user->applicants()->with('blood_group')->where('visible', 1)->get();
return view('applicants.index', ['applicants' => $applicants]);
}
Then you can access $applicants in your blade file like so:
#foreach($applicants as $applicant)
<div class="row mx-4">
<div class="col-06 pr-3">
<p class="h5">Name:</p>
</div>
<div class="col-06">
<p>{{$applicant->blood_group->name}}</p>
</div>
</div>
#endforeach
Hope this helps.

Related

Laravel8 | Vuex: POST error 500 (Internal Server Error)

I've been learning Vue and Laravel for the last 2 months and recently I started to work on a project in order to apply all the knowledge I've learned so far. I set several GET and POST routes successfully but for some reason, this request keeps failing.
I'm trying to set a simple POST request using Vuex, Laravel and Axios but I keep on getting the 500 (Internal Server Error) and I'm not sure what is causing it. I have the feeling that it may be that the Model is not correctly set up, bcs if I output the data that the controller received, it looks correct but when I instantiate the model and save the data to DB I get the error.
I would really appreciate any help or feedback on my code since I'm in a early stage of my learning curve and there are some things that I'm sure could be optimized.
Route:
//StreamingProviders
Route::get('/api/all-streaming-providers', [StreamingProviderController::class, 'getAllStreamingProviders']);
Route::post('/api/add-streaming-providers', [StreamingProviderController::class, 'addStreamingProviders']);
Controller:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Repository\Dictionaries\StreamingProvidersList;
use App\Models\StreamingProvider;
class StreamingProviderController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function getAllStreamingProviders()
{
$streamingProviders = StreamingProvidersList::$map;
return response()->json([
'allProviders' => $streamingProviders
]);
}
public function addStreamingProviders(Request $request, StreamingProvider $userStreamingProviders)
{
$user = auth()->user();
$data = $request->all();
$userStreamingProviders = new StreamingProvider();
$userStreamingProviders->user_id = $user['id'];
$userStreamingProviders->Netflix = $request->input('Netflix');
$userStreamingProviders->Amazon_Prime_Video = $request->input('Amazon Prime Video');
$userStreamingProviders->Sky_Ticket = $request->input('Sky Ticket');
$userStreamingProviders->Disney_Plus = $request->input('Disney Plus');
$userStreamingProviders->HBO_Video = $request->input('HBO Video');
$userStreamingProviders->save();
return response()->json([
'streamingProviders' => $userStreamingProviders
]);
}
}
FormComponent.vue
<template>
<div class="container">
<div class="row justify-content-center">
<div class="card">
<div class="card-header">
<h2>Select your streaming country</h2>
</div>
<form #submit.prevent="updateUserDetails()">
<div class="card-body">
<div class="form-control">
<select class="selectpicker" id="countryList">
<option v-for="(value, name) in getCountriesList" :key="name" :value="name">
{{ value }}
</option>
</select>
</div>
<div v-for="(value, name) in getAllStreamingProviders" :key="name" class="form-check">
<input v-model="streamingProviders[value]"
type="checkbox"
:id="name"
:value="value"
:name="streamingProviders[value]"
class="form-check-input" />
<label>{{ value }}</label>
</div>
</div>
<div class="card-footer">
<button type="submit" class="btn btn-success center-text">Save</button>
</div>
</form>
</div>
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
import router from '../../routes/index';
export default {
name: 'edituserdetails',
data() {
return {
value: '',
streamingProviders: {
'Netflix': false,
'Amazon Prime Video': false,
'Disney Plus': false,
'HBO Video': false,
'Sky Ticket': false
}
}
},
created() {
this.$store.dispatch('getCountriesList'),
this.$store.dispatch('getAllStreamingProviders')
},
methods: {
updateUserDetails() {
const country = {
'id': $('#countryList').children("option:selected").val(),
'name': $('#countryList').children("option:selected").text()
};
this.$store.dispatch('updateUserStreamingProviders', this.streamingProviders);
this.$store.dispatch('updateCountry', country).then(() => {
router.push('/user-settings');
});
}
},
computed: {
...mapGetters(['getCountriesList', 'getAllStreamingProviders']),
}
}
</script>
Vuex store:
import axios from "axios";
const state = {
userName: "",
country: "",
countriesList: {},
allStreamingProviders: {},
userStreamingProviders: []
};
const mutations = {
UPDATE_USERNAME(state, payload) {
state.userName = payload;
},
GET_COUNTRIES_LIST(state, payload) {
state.countriesList = payload;
},
UPDATE_COUNTRY(state, payload) {
state.country = payload;
},
GET_ALL_STREAMING_PROVIDERS(state, payload) {
state.allStreamingProviders = payload;
},
UPDATE_STREAMING_PROVIDERS(state, payload) {
state.userStreamingProviders = payload;
}
};
const actions = {
updateUserData({ commit }) {
axios.get("/api/user").then(response => {
commit("UPDATE_USERNAME", response.data.name);
commit("UPDATE_COUNTRY", response.data.country);
});
},
getCountriesList({ commit }) {
axios.get("/api/countries-list").then(response => {
commit("GET_COUNTRIES_LIST", response.data.list);
});
},
updateCountry({ commit }, country) {
axios
.post("/api/update-country", country)
.then(response => {
commit("UPDATE_COUNTRY", response.data.country);
})
.catch(err => {
console.log(err);
});
},
getAllStreamingProviders({ commit }) {
axios.get("/api/all-streaming-providers").then(response => {
commit("GET_ALL_STREAMING_PROVIDERS", response.data.allProviders);
});
},
updateUserStreamingProviders({ commit }, streamingProviders) {
axios
.post("/api/add-streaming-providers", streamingProviders)
.then(response => {
commit(
"UPDATE_STREAMING_PROVIDERS",
response.data.streamingProviders
);
})
.catch(err => {
console.log(err);
});
}
};
const getters = {
getUserName: state => state.userName,
getCountry: state => state.country,
getCountriesList: state => state.countriesList,
getAllStreamingProviders: state => state.allStreamingProviders
};
const userStore = {
state,
mutations,
actions,
getters
};
export default userStore;
Streaming Provider Model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class StreamingProvider extends Model
{
use HasFactory;
/**
* Attributes that are mass assignable
*
* #var array
*/
protected $fillable = ['user_id', 'Netflix', 'Amazon_Prime_Video', 'Sky_Ticket', 'Disney_Plus', 'HBO_Video'];
protected $table = 'streaming_provider';
protected $cast = [
'Netflix' => 'boolean',
'Amazon_Prime_Video' => 'boolean',
'Sky_Ticket' => 'boolean',
'Disney_Plus' => 'boolean',
'HBO_Video' => 'boolean'
];
public function user()
{
return $this->belongsTo(User::class);
}
}
Do I have to cast the data before saving it to DB?
Are the boolean properties considered $fillable ??
migration:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class StreamingProvidersTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('streaming_provider', function (Blueprint $table) {
$table->id();
$table->string('user_id');
$table->boolean('Netflix')->default(0);
$table->boolean('Amazon_Prime_Video')->default(0);
$table->boolean('Sky_Ticket')->default(0);
$table->boolean('Disney_Plus')->default(0);
$table->boolean('HBO_Video')->default(0);
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('streaming_provider');
}
}
Laravel.log:
[2021-10-27 09:12:39] local.ERROR: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'updated_at' in 'field list' (SQL: insert into `streaming_provider` (`user_id`, `Netflix`, `Amazon_Prime_Video`, `Sky_Ticket`, `Disney_Plus`, `HBO_Video`, `updated_at`, `created_at`) values (1, 1, 1, 0, 0, 0, 2021-10-27 09:12:39, 2021-10-27 09:12:39)) {"userId":1,"exception":"[object] (Illuminate\\Database\\QueryException(code: 42S22): SQLSTATE[42S22]: Column not found: 1054 Unknown column 'updated_at' in 'field list' (SQL: insert into `streaming_provider` (`user_id`, `Netflix`, `Amazon_Prime_Video`, `Sky_Ticket`, `Disney_Plus`, `HBO_Video`, `updated_at`, `created_at`) values (1, 1, 1, 0, 0, 0, 2021-10-27 09:12:39, 2021-10-27 09:12:39)) at C:\\xampp\\htdocs\\laravel_vue\\Fullstack_Project_Movie_III\\vendor\\laravel\\framework\\src\\Illuminate\\Database\\Connection.php:703)
[previous exception] [object] (PDOException(code: 42S22): SQLSTATE[42S22]: Column not found: 1054 Unknown column 'updated_at' in 'field list' at C:\\xampp\\htdocs\\laravel_vue\\Fullstack_Project_Movie_III\\vendor\\laravel\\framework\\src\\Illuminate\\Database\\Connection.php:486)
Thanks you all!!
You have this error because $table->timestamps(); is missing from your migration so you have to add it, Laravel will automatically create updated_at and created_at column for you.
For every entry and update in laravel it automatically assign value to these columns, so obviously you get this error when they are missing from your database.
After, your migration will look like this:
`Schema::create('streaming_provider', function (Blueprint $table) {
$table->id();
$table->string('user_id');
$table->boolean('Netflix')->default(0);
$table->boolean('Amazon_Prime_Video')->default(0);
$table->boolean('Sky_Ticket')->default(0);
$table->boolean('Disney_Plus')->default(0);
$table->boolean('HBO_Video')->default(0);
$table->timestamps();
});`

laravel-medailibrary getFirstMediaUrl("images") not work for joined tables

I have a problem getting media from a joined table in laravel-medailibrary, I used getFirstMediaUrl("images") to get photos from one table and it works, but if I join two or three tables it not work, how can I solve it?
I want to get photos from those posts that shared by a user.
this post table:
this is share_tb table:
this is users table:
this is the media table:
I find my answer after trying some ways:
public function getPosts(Request $request)
{
$result = [];
$postID = DB::table("share_tb")->where("user_id", Auth::user()->id)->get();
foreach ($postID as $id) {
if (count(Post::where("id", $id->related_id)->get()) > 0) {
$posts = Post::where("id", $id->related_id)->get();
foreach ($posts as $post) {
// $result = $post->getMedia('images');
array_push($result, [
"comment_count" => getTotalComment($post->id),
"course_id" => $post->course_id,
"id" => $post->id,
'post_image' => count($post->getMedia('images')) > 0 ? $post->getMedia('images')[0]->getFullUrl('big') : "",
'logo'=>GetCourseLogo::collection(Course::where('course_id',$post->course_id)->get()),
"post_author" => $post->post_author,
"post_date" => $post->post_date,
"post_excerpt" => $post->post_excerpt,
"post_modified" => $post->post_modified,
"post_parent" => $post->post_parent,
"post_title" => $post->post_title,
"post_type" => $post->post_type,
]);
}
}
}
return Response()->json($result);
}
and by this resource collection, I get the logo:
class GetCourseLogo extends JsonResource
{
public function toArray($request)
{
return $this->getFirstMediaUrl('logo');
}
}

Trying to get property 'id' of non-object laravel

can someone to help me ? i have an error Trying to get property 'id' of non-object laravel while try to show my edit form
this is my controller
public function edit($id)
{
$produk = produk::where('id',$id)->first();
return view('produk.edit',compact('produk'));
}
public function update(Request $request, $id)
{
produk::where('id',$id)
->update([
'nama' => $request->nama,
'id_kategori' => $request->kategori,
'qty' => $request->qty,
'harga_beli' => $request->beli,
'harga_jual' => $request->jual,
]);
return redirect()->route('produk.index');
}
this is my model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class produk extends Model
{
protected $guarded = ['id','created_at','updated_at'];
public function kategoris()
{
return $this->hasOne('App\kategori', 'id', 'id_kategori');
}
}
and this is my view
<select class="form-control" name="kategori">
<option value="Pilih Kategori"></option>
#foreach ($produk as $k)
<option value="{{ $k->id }}" #if($produk->id_kategori == $k->id) selected #endif>{{$k->nama}}</option>
#endforeach
</select>
Its because of this
$produk = produk::where('id',$id)->first();
this returns an object not an array of object. thats why your getting an error on your view. Instead use:
$produk = produk::where('id',$id)->get();
to return an array of object.
You are trying to foreach trough product properties, but looks like you need to foreach trough collection of categories.
Add categories to view in controller:
public function edit($id)
{
$produk = produk::find($id);
$kategoris = kategori::all();
return view('produk.edit',compact('produk', 'kategoris'));
}
Iterate trough $kategoris (not $produk) in View:
<select class="form-control" name="id_kategori">
<option value="Pilih Kategori"></option>
#foreach ($kategoris as $kategori)
<option value="{{ $kategori->id }}" #if($produk->id_kategori == $kategori->id) selected #endif>{{$kategori->nama}}</option>
#endforeach
</select>
Also, if foreign key is id_kategori, it is better to use name=id_kategori istead of name=kategori
You don't need relation here, because you compare categories ids with id_kategori attribute. But you should replace hasOne to belongsTo in this case.
public function kategoris()
{
return $this->belongsTo('App\kategori', 'id_kategori');
}
The correct way to obtain the value of the arrangement is
$k["id"] and not $k->id
I tried to obtain a field incorrectly with the array, I received the following array
[{"id": 1, "name": "Ivania", "code": 387}, {"id": 2, "name": "Robert", "code": 389}]
Check the array with a foreach
$users = $request->input('users');
foreach($users as $key => $user)
$person = new Person();
//incorrect form
//$person->id = $user->id
//the correct form
$person->id = $user["id"];
$person->name = $user["name"];
$person->code = $user["code"];
$person-> save ();
}

laravel - change value in array for API Resources

{
"data": {
"username": "candy",
"certificates": [
{
"id": 11,
"category_id": 1,
"certname": "cert name test",
"created_at": "2018-08-18 00:58:12",
"updated_at": "2018-08-18 00:58:12"
}
]
}
}
Above is a response by using Eloquent: API Resources.
I would like to put category name instead of category_id.
Below is resource class
public function toArray($request)
{
return [
'nickname' => $this->nickname,
'certificates' => $this->certificates,
];
}
certificates are in array (hasMany relationship)
certificates belongsTo category
In this case, in the resource class you can fetch category name for each certificate and attach it.
public function toArray($request)
{
$certificateList = $this->certificates;
foreach($certificateList as $ceritificate) {
// fetch only the category name from the database.
// attach to the certificate.
$categoryName = Category::where('id', $certificate->category_id)->pluck('name')->first();
$certificate->setAttribute('category_name, $categoryName);
}
// then as usual
return [
'nick_name' => $this->nick_name,
'certificates' => $certificateList
];
}
This Might Help,
Run a foreach loop
$category = "Your SELECT Query";
foreach ($category as $value) {
$categoryId = json_decode($value->category_id);
$x = Category::select('certname')->whereIn('id', $categoryId)->get();
foreach ($x as $as) {
$y[] = $as->certname;
}
$value->certname = $y;
you can just do it like this
in controler
return CertificateResource::collection(Certificate::with('category')->get());
in CertificateResource
return [
'nickname' => $this->nickname,
'certificates' => $this->certificates,
'category_name'=>$this->whenLoaded('category', function () {
return $this->category->category_name;
}),
];

Relationship data to view - Laravel 5.2

Having a Problem to output a relationship data to view.
Error message is: "Trying to get property of non-object View".
For explanation all Task depend to a job.
So Task belongsTo Job and Job hasMany tasks.
I have all Relationships in my Models and test it in Tinker everything works.
In my view I Output every Task name and the job name
#foreach ($tasks as $task)
<div class="list-item">
<span class="item-name">{{ $task->job->name }}
<span class="item-name">{{ $task->name}} </span>
</div>
#endforeach
The index function of my TaskController:
public function index(Request $request)
{
$label = Label::all();
$user = User::all();
$task = Task::orderBy('duedate')->get();
$team = Team::all();
$customer = Customer::all();
$status = Status::all();
$job = Job::all();
return view('tasks.index')->with([
'tasks' => $task,
'teams' => $team,
'customers' => $customer,
'labels' => $label,
'users' => $user,
'jobs' => $job,
'statuses' => $status,
]);
}
Table schema / output from tinker
id: 1,
assigned_user_id: 1,
team_id: 4,
name: "Label many to many ",
duration: 2,
created_at: "2016-06-16 14:50:57",
updated_at: "2016-07-05 09:10:34",
job_id: 1,
duedate: "0000-00-00 00:00:00",
status_id: 3,
job: App\Job {#702
id: 1,
name: "quia",
jobnumber: "8076",
customer_id: 2,
status_id: 0,
created_at: null,
updated_at: null,
},
user: null,
Relationships
**Job Model **
class Job extends Model
{
protected $fillable = ['name', 'jobnumber', 'customer_id', 'status_id'];
/**
* Get all Task for Job
*/
public function task()
{
return $this->hasMany(Task::class);
}
Task model
public function job()
{
return $this->belongsTo(Job::class);
}
Hope you can help me, thanks!
With reference to your answer:
In the DB some Task entries had an job_id to an none exisiting Job
You can use has method to limit your results based on the existence of a relationship. see doc for querying relationship absence
$task=Task::orderBy('duedate')->has('job')->get();
This kind o f error occurs when you are trying to print a model value that doesn't exists. Try to print using {{isset($task->job->name)?$task->job->name:'Task without Job'}} and check what it outputs.
You don't load the "job" relationship on $task before trying to access it's values :
public function index(Request $request)
{
$label = Label::all();
$user = User::all();
$task = Task::with('job')->orderBy('duedate')->get(); // loading the relationship
$team = Team::all();
$customer = Customer::all();
$status = Status::all();
$job = Job::all();
return view('tasks.index')->with([
'tasks' => $task,
'teams' => $team,
'customers' => $customer,
'labels' => $label,
'users' => $user,
'jobs' => $job,
'statuses' => $status,
]);
}
Found the solution.
In the DB some Task entries had an job_id to an none exisiting Job, thats it.

Resources