Retrieving error on one to many relationship laravel - php

Been learning laravel for 4 days and im trying to fix this error for 2 hours and i cant still fix it. I can save on one to many relationship but i cant retrieve data i think there something wrong with the relationship. Im trying to retrieve posts on user using this line but im getting not empty results on users but empty result on posts. Same thing happening on categories and posts which is many to many relationship but i cant save on many to many.
$users = User::with('posts')->get();
ANd im getting an error when i use this the error is
Undefined property: Illuminate\Database\Eloquent\Collection::posts()
$users = User::where('user_id','=','2')->get();
$posts = $users->posts()->get();
Heres my user Model
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
protected $primarykey = 'user_id';
protected $table = 'users';
public function posts(){
return $this->hasMany("App\Post");
}
}
Heres my posts Model
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
protected $primarykey = 'id';
protected $table = 'posts';
public function post_validation_rules(){
return [
'post_title' => 'required|min:5|unique:posts',
'post_body' => 'required'
];
}
public function user(){
return $this->belongsTo("App\User");
}
public function categories(){
return $this->belongsToMany('App\Category', 'category_id', 'category_id');
}
}
Categories Post
class Category extends Model
{
protected $primarykey = 'category_id';
protected $table = 'categories';
public function posts(){
return $this->belongsToMany('App\Post', 'post_id', 'id');
}
}
Database
Posts Table
id
user_id
post_title
post_body
createad_date
updated_date
Users Table
user_id
username
email
pass
createad_date
updated_date

You can only call relations on a single object, not on an entire collection. $users is a collection of User objects.
If you want a single user object, use the first() function to get the first User object that matches.
$user = User::where('user_id','=','2')->first();
$posts = $user->posts;
Update:
To get the posts directly in the user object, you need to use the with function:
$user = User::with('posts')->where('user_id','=','2')->first();

Try to declare the field that have the relation between your tables then, for example:
$this->hasMany(App\Post::class, 'user_id', 'user_id');
Laravel is searching for a field id in User table but it does not exist. so with this way you will tell it that the field you look is user_id

Related

Laravel framework eloquent relationship query

I have created relationship between 4 tables.
This are my models:
User
BusinessInfo
ElectrcityInfo
GasInfo
This are the primery keys that I am using in my tables:
user_id (to get login users data from BusinessInfo)
contract_id (This also exists in BusinessInfo I am use it to get data from the other two tables for specific records)
Now I want to get all login users data from BusinessInfo table and each BusinessInfo row has its own 1 row data from ElectricityInfo and GasInfo.
When I am use contract_id in model its give me relationship result null.
When it is on user_id its display only 1 ElectrcityInfo with all records.
Controller
$user = Auth::user();
$business = BusinessInfo::where('user_id', $user->id)->first();
$data = $business->electricity()->paginate(6);
return view('Pages.MySite', ['data' => $data]);
BusinessInfo Model
protected $primaryKey = 'contract_id';
public $table = "business_info";
protected $guarded = [];
public $timestamps = false;
public function electricity()
{
return $this->belongsTo('App\Models\ElectricityInfo', 'contract_id');
}
public function gas()
{
return $this->belongsTo('App\Models\GasInfo', 'contract_id');
}
You BusinessInfo model is missing the user relationship. Put this in your code:
public function user()
{
return $this->belongsTo('App\Models\User', 'user_id');
}
Your query is not right
When it is on user_id its display only 1 ElectrcityInfo with all records.
This is because you use the first() method wich returns the first object from the collection. You should use this:
$businesses = BusinessInfo::where('user_id', $user->id)->get();
This will return all objects according to the query.
Now you can loop the $business array and access each information
foreach($businesses as $business)
{
$business->electricity()->first(); // this will return all your data from the BusinessInfo relation with the ElectricityInfo model
$business->gas()->first(); // this will return all your data from the BusinessInfo relation with the GasInfo model
}
For more info about the first() method and other methods click here
You also could take a look at the Eloquent: Relationships section to know more about how it works
In your view:
#foreach($businesses as $business)
{
{{$business->electricity()->first()}}
{{$business->gas()->first()}}
}
#endforeach

Laravel select quizzes belonging to current user

I'm currently working on a quiz application in laravel 5.6 and am attempting to fetch all quizzes that belong to the current authenticated user.
I have three tables:
users
quizzes
user_quizzes
The quizzes table simply holds all the information relating to the quiz such as:
- id
- quiz_name
- quiz_description
- active
- total_plays
- created_at
- updated_at
The users table is just the laravel default with minor changes:
- id
- username
- email
- password
- remember_token
- created_at
- updated_at
The user_quizzes table holds two fields (both foreign keys): user_id and quiz_id.
At the moment it outputs ALL the quizzes, rather than just ones belonging to the current user.
In my QuizController I have:
$quizzes = Quiz::find(Auth::user()->id)->with('user')->get();
And my QuizModel:
class Quiz extends Model
{
protected $table = 'quizzes';
public function user()
{
return $this->belongsTo('App\Models\User');
}
}
Finally the UserModel contains:
class User extends Authenticatable
{
use Notifiable;
protected $fillable = [
'username', 'email', 'password',
];
protected $hidden = [
'password', 'remember_token',
];
public function activation()
{
return $this->hasOne('App\Models\Activation');
}
public function profile()
{
return $this->hasOne('App\Models\Profile');
}
public function quizzes()
{
return $this->hasMany('App\Models\Quiz');
}
}
I have also tried using the DB facade with joins but received the same output (all quizzes returned, not just ones belonging to the current user). Here is what I did for that, just for reference:
$quizzes = DB::table('user_quizzes')
->join('users', 'users.id', '=', 'user_quizzes.user_id')
->join('quizzes', 'quizzes.id', '=', 'user_quizzes.quiz_id')
->get();
I feel like I am making a silly mistake, so any guidance would be greatly appreciated.
You need to change Eloquent relationship in the Model.
class User extends Model {
public function quizzes()
{
return $this->belongsToMany(Quiz::class, 'user_quizzes','user_id', 'quiz_id');
}
}
Same with Quiz Model
class Quiz extends Model
{
protected $table = 'quizzes';
public function user()
{
return $this->belongsToMany(User::class, 'user_quizzes','quiz_id', 'user_id');
}
}
DB facade you're doing incorrectly.
You want to fetch all quizzes for the users so you need to query quizzes table like this.
DB::table('quizzes')->leftJoin('user_quizzes', 'user_quizzes.quiz_id', 'quizzes.id')->join('users', 'user_quizzes.user_id', 'user_id')->where('users.id', $USER_ID)->get();

Laravel Eloquent belongsto relationship returns null

I have two Eloquent models:
1) Post
class Post extends Model
{
protected $table = 'posts';
protected $fillable = ['id', 'user_id', 'product_id', 'site_id', 'link_id', 'body', 'created_at', 'updated_at'];
public function user(){
return $this->belongsTo(User::class);
}
public function product(){
return $this->belongsTo(Product::class);
}
2) Product
protected $table = 'products';
protected $fillable = ['id', 'user_id', 'manufacturer_id', 'shift_product_id', 'name', 'english_name',
'slug', 'text', 'spec', 'live', 'created_at', 'updated_at'];
public function posts(){
return $this->hasMany(Post::class);
}
I need to get the product from a post
I do that:
$posts = Post::get();
foreach($posts as $key){
dd($key->product);
}
Like this it returns NULL
If I do like this:
dd($key->product());
I get the product but I can't to use that
but I need to get something like that to use whant I need:
Try to point out foregin key and other key in relation, examples:
public function post()
{
return $this->belongsTo('App\Post', 'foreign_key', 'other_key');
}
public function user()
{
return $this->belongsTo('App\User', 'foreign_key', 'other_key');
}
More: https://laravel.com/docs/5.5/eloquent-relationships
i found my problem
i dont have in the DB product with ID = 1
:/
stuped problem
thanks for all the help i leran alot from u.
The relationship probably doesn't exist in the database.
Based on your fillable array on Post, the way you have the relationships setup looks correct as you are following naming conventions for keys and your belongsTo relationship methods have the correct name for convention.
$post->product() is not returning your Product model. It is returning a Relation type object (BelongsTo). This is used for querying the relationship. $post->product would be the dynamic property for the relationship that would return the already loaded relationship or load the relationship and give you the result.
Laravel 5.5 Docs - Eloquent - Relationships - Relationship Methods Vs. Dynamic Properties
If the relationships are setup correctly $post->product being null would mean the relationship doesn't actually exist in the database, no matching id in products for product_id or product_id being null. (assuming no foreign key constraint)
Side note: eager loading the relationship would be a good idea:
$posts = Post::with('product')->get();
I just came across this post because I got a similar error while working on a project.
What I discovered is that when you query a model with the all() method, it ignores the related softdeleted rows.
When you try to access them tho, you get the null
Remember to hit save() after associate and dissociate. Got me a couple of times:
$model->relation()->associate($record)->save();

Laravel 5 – get particular many to many relation based on model and related model ID

I've got Tag and Attendee Eloquent models, they are in many-to-many relation. Pivot table has also two more attributes – value_int and value_string. My Attendee model looks like this:
class Attendee extends Model
{
public $timestamps = false;
protected $fillable = [
'event_id'
];
public function tags() {
return $this->belongsToMany('App\Models\Tag', 'attendee_tag', 'attendee_id', 'tag_id')
->withPivot(['value_string', 'value_int']);
}
public function scoreTagValue($tag_id) {
return $this->tags->where('tag_id', '=', $tag_id)->first();
}
}
What I want is to obtain pivot values based on Attendee model and variable tag_id, so I've written scoreTagValue function, but it always returns null and I don't know why :( I'm calling it this way:
$attendee->scoreTagValue($tag_id). Thanks for your help :)
You need to access the relation, not the property:
public function scoreTagValue($tag_id) {
return $this->tags()->where('tag_id', '=', $tag_id)->first();
}
Also, according to the docs, withPivot() does not take an array, so:
->withPivot('value_string', 'value_int');

how to convert joins query to laravel eloquent query

I have query bulider's query like this
$schedule = DB::table('users')
->join('tblHomeCourts','users.homeCourtId','tblHomeCourts.homeCourtId')
->join('tblUserHomeCourts','tblUserHomeCourts.userId','users.userId')
->join('tblSchedules','tblUserHomeCourts.userHomeCourtId','tblSchedules.userHomeCourtId')
->select('tblHomeCourts.homeCourtName', 'tblHomeCourts.address','tblSchedules.timeFrom','tblSchedules.timeTo','tblSchedules.duration','tblSchedules.scheduleStatus','users.firstName','users.lastName','users.profilePic','users.userId')
->where(['tblSchedules.scheduleStatus'=> 0,
])->where('timeFrom','>',$request->currentTime)
->where('timeTo','>',$request->currentTime)
->where('tblUserHomeCourts.homeCourtId',$homeCourtId)
->get();
Now, I want to convert this into proper eloquent query using eloquent relationship I'm fully messed up with relationships can somebody please help me to find out the solution?
thanks :)
To achieve this we have to define relationships among the related table for the first place. Then we need to load the joint table using the with method.
For example you User model should look like this:
class User extends Model{
protected $table = 'users';
public function homeCourt(){
//Many to one relation between user and homeCourt
return $this->belongsTo(HomeCourt::class, 'homeCourtId', 'homeCourtId');
}
public function userHomeCourts(){
//One to many relation between user nad userHomeCourt
return $this->hasMany(UserHomeCourts::class, 'userId', 'userId');
}
}
Your HomeCourt model should look like:
public class HomeCourt extends Model{
protected $table = 'tblHomeCourts';
public function user(){
//One to many relation between homeCourt and user
return $this->hasMany(User::class, 'homeCourtId', 'homeCourtId');
}
}
Your UserHomeCourt model should look like:
public class UserHomeCourt extends Model{
protected $table = 'tblUserHomeCourts'
public function user(){
//Many to one relation between userHomeCourts and users
return $this->belongsTo(User::class, 'userId', 'userId');
}
public function schedules(){
//One to many relation between userHomeCourts and schedule
return $this->hasMany(Schedule::class, 'userHomeCourtId', 'userHomeCourtId');
}
}
Your Schedule model should look like:
public function Schedule extends Model{
protected $table = 'tblSchedules';
public function userHomeCourt(){
//Many to one relation between schedule and userHomeCourts
return $this->belongsTo(UserHomeCourt::class, 'userHomeCourtId', 'userHomeCourtId');
}
}
Now you are ready to build your query. This query is bit different than the query you have built using query builder. Besides, the output of laravel eloquent query is also different. You have to adjust that result with you view:
You can query like this:
$users = User::with('homeCourt', 'userHomeCourts.schedule')->where('timeTo', '>', ,$request->currentTime)->get();
This query is just an example, you have to define it according to your requirement. Here, the parameters of with methods are the methods name of that users table relation with other tables. This is how it works.
You can read more here: https://laravel.com/docs/5.4/eloquent-relationships

Categories