Laravel One To Many Relationship - laravel

I have an Author model and Blog model.
I also set up a table with the author_id and blog_id. The table is called "author_blog".
Below is how I am defining my relationships:
Author Model:
public function blogs()
{
return $this->hasMany('App\Blog', 'author_id');
}
Blog Model:
public function author()
{
return $this->belongsTo('App\Author', 'blog_id');
}
In my view I am trying to do $blog->author->first_name. The first name is a column on the Authors table.
I keep getting
trying to get property on non-object.
Any ideas?
UPDATE:
I have removed the intermediate table and instead put an "author_id" on my blogs table and shortened it as such.
Author Model:
public function blogs()
{
return $this->hasMany('App\Blog');
}
Blog Model:
public function author()
{
return $this->belongsTo('App\Author');
}
In my BlogController, when I define the view, I grab a collection of blogs via $blogs = Blog::all();
In my view I just loop through the blogs to show each individually like...
#foreach ($blogs as $blog)
<div>{{ $blog->author->first_name }}</div>
#endforeach

For one to many relationship you don't need another table to handle your foreign key.
Just add author_id foreign key with your blogs table. then define your relations
like below,
Author Model:
public function blogs()
{
return $this->hasMany('App\Blog', 'author_id');
}
Blog Model:
public function author()
{
return $this->belongsTo('App\Author', 'author_id');
}
view:
before that make sure your query return a valid collection.
#foreach ($blogs as $blog)
<div>#if( $blog->author) {{ $blog->author->first_name }} #endif </div>
#endforeach
For further more details : https://laravel.com/docs/5.8/eloquent-relationships#one-to-many

with belongsToMany relation you can define your middle table(author_blog)
In Author model:
public function blogs()
{
return $this->belongsToMany(Blog::class,'author_blog','author_id','blog_id');
}
author_blog => middle table
author_id => foreignPivotKey
blog_id => relatedPivotKey

Related

Fetching data from two tables in Laravel in show function in controller?

I have two Model, School, and Student the relationship is, School has Many Student
//Student Model
public function school()
{
return $this->belongsTo('App\School');
}
and same in School Model the following is the function for relationship
public function student()
{
return $this->hasMany('App\Student');
}
Now I have a show Page I like to display the following information. (school_name,school_code) from the school table and student information all from the Student Table.using show function in student controller if I pass as
public function show($id)
{
$student=Student::find($id);
$school=School::find($id);
return View::make('student.show')->with(['school'=> $school,'student'=>$student]);
}
it gets data from school if school_id ==$id but one school has many students it fails if I click to show a button with an ID of 109, how to write the Join query to get school_code and school_name from schools table.
Not sure why you are using the same $id to getting student and school
public function show($id)
{
$student = Student::find($id);
$school = $student->school; //school of the student
return View::make('student.show')->with(['school'=> $school,'student'=>$student]);
}
Use this code
Your model should be like this
public function students()
{
return $this->hasMany('App\Student');
}
You have to change like this.
$student = Student::find($id);
$school = $student->school;
Since you have the relationship setup already, you could use Eloquent to fetch data for single student with the school that he belongs tos as follow:
public function show($id)
{
$student = Student::with('school')->where('id', $id)->first();
return View::make('student.show')->compact('student);
}
Now you can retrieve data show.blade.php as follow:
#foreach($student as $stud)
<li> {{ $stud->student_name}}</li>
<li> {{ $stud->student_code}}</li>
<li> {{ $stud->->school->school->name}}</li>
<li> {{ $stud->school->school_name }}</li>
#ndforeach

Laravel Eloquent Relationship has the same foreign key on the same table

I'm a beginner in Laravel and currently trying to create a ticketing system. My tickets table has two columns which both reference id from the users table namely user_id and handled_by. I am trying to eager load the full_name of handled_by but it is throwing an error "Trying to get property 'full_name' of non-object". I would like to know how to properly create an eloquent relationship between handled_by and tickets so I could display the handled_by's full_name. Below are snippets of my code.
User Model:
public function tickets(){
return $this->hasMany('\App\Ticket');
}
public function handledBy(){
return $this->hasMany('\App\User', 'handled_by', 'id');
}
Ticket Model:
public function user(){
return $this->belongsTo('\App\User');
}
public function handledBy(){
return $this->belongsTo('\App\User', 'handled_by', 'id');
}
View:
#foreach($tickets as $ticket)
<td class="align-middle text-center">{{ $ticket->handled_by->full_name}}</td>
#endforeach
Controller:
$tickets = Ticket::all()->where('status_id', '1');
return view('admin.open_tickets', compact('tickets'));
In your User model, change \App\User to \App\Ticket, and change the method name from handlerBy to handlers:
public function handlers(){
return $this->hasMany('\App\Ticket', 'handled_by', 'id');
}
And call it by method's name instead of underline case name:
{{ $ticket->handledBy->full_name}}

Same Foreing Key Twice That Refers to One Model

I need to make an advice platform for products. User can make advices under product section. So product has many advices. Also advices belongsTo product. But on product_advices table i have product_id and product_advice_id these both refers to id on products table.
So here is the problem. I can take advices from product_advices table which refers to product_id. But how can i take the other one as product.
product->advices to show advice and user message
each advices as advice and advice->product->name to show adviced product name
I couldn't make a relationship with eloquent between them.
//Product Model
public function advices()
{
return $this->hasMany('App\ProductAdvice', 'product_id');
}
//ProductAdvice Model
protected $table = 'product_advices';
public function product() {
return $this->belongsTo('App\Product', 'product_id');
}
//Product Advice Table
Schema::create('product_advices', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->text('body')->nullable();
$table->integer('product_id')->unsigned();
$table->foreign('product_id')->references('id')->on('products')->onDelete('cascade');
$table->integer('product_advice_id')->unsigned();
$table->foreign('product_advice_id')->references('id')->on('products')->onDelete('cascade');
$table->timestamps();
});
For example :
Iphone has many advices by users.
Iphone->advices brings the advices from product_advices that Iphone belongs to product_id column.
When User recommends Samsung Galaxy S10 to Iphone. Samsung refers to product_advice_id column on product_advices table. But how to show Samsung Galaxy S10 as a product.
$advice->product->name returns Iphone instead of Samsung Galaxy S10.
EDIT 2
After your answer, I understood what you want.
Just update your ProductAdvice model to have another relationship, like:
class ProductAdvice extends Model
{
public function product()
{
return $this->belonsTo('App\Product', 'product_id');
}
public function related()
{
return $this->belonsTo('App\Product', 'product_advice_id');
}
}
Then you can do:
$product = Apple
$product->advices->message = 'blablabla'
$product->advices->related = 'ProductX'
If you need to to the inverse order, $advice->product->related add the same relationship on your Product model.
EDIT 1
Sorry, you edited the post after my answer...
Could you explain the 'product_advice_id' necessity? You already have the product_id.
Unless you want a pivot table, like: Product -> ProductAdvice -> Advice, which is not needed in your case, since you can just put the advice information in the Advice table and link it to the product (belongsTo), removing the necessity of the ProductAdvice pivot.
I think your structure should be like this:
Product model with all the product data
ProductAdvice model with product_id and the advice information (message, rating, etc)
Then, your Product hasMany Advices and your Advice belongsTo Product:
class Product extends Model
{
public function advices()
{
return $this->hasMany('App\ProductAdvice', 'product_id');
}
}
class ProductAdvice extends Model
{
public function product()
{
return $this->belonsTo('App\Product', 'product_id');
}
}
Finally, you can query the advices of a specific Product to get the advice information:
$product->advices->message
$product->advices->rating
Or query the product name if you have an advice:
$advice->product->name
So, If understand well, you want and advice from product A to return the name of product B.
You can make this by creating multiple method related to the same model.
Your models will look similar at this:
class Product extends Model
{
public function advices()
{
return $this->hasMany('App\ProductAdvice', 'product_id');
}
public function relations()
{
return $this->hasMany('App\ProductAdvice', 'related_id');
}
}
class ProductAdvice extends Model
{
public function product()
{
return $this->belonsTo('App\Product', 'product_id');
}
public function relation()
{
return $this->belonsTo('App\Product', 'related_id');
}
}
Then you will have to create another column in your talbe name :related_id (it could be something else, just made it match in your model. You can also change relations() and relation() method to whatever name you want.)
After this it's how you store your data. You have to make your code associate the good product model into your product_id and into related_id. This way. You can have $advice->product->name === 'iPhone' && $advice->relation->name === 'Samsung S10'
Found a solution like this for now.
//ProductAdvice Model
protected $table = 'product_advices';
public function user()
{
return $this->belongsTo('App\User');
}
public function product() {
return $this->belongsTo('App\Product', 'product_id');
}
public function advicedProduct()
{
return Product::where('id', $this->product_advice_id)->first();
}
//Product Model
public function advices()
{
return $this->hasMany('App\ProductAdvice', 'product_id');
}
How i show it on view
#foreach($product->advices as $advice)
<li>{{ $advice->body }} - {{ $advice->advicedProduct()->name }}</li>
#endforeach

Trying to retrieve posts from table by category slug

Hello i am trying to loop posts that are associated to each category by the slug. It works when i use the ids but when i change my controller function to search by slug it retrieves the slug but does not load the foreach loop.
I have tried so many methods and i don't know where i am going wrong please help.
Category Model :
protected $table = 'post_categories';
public function posts()
{
return $this->hasMany('App\Post', 'id', 'name', 'catslug');
}
Post Model
public function user()
{
return $this->belongsTo('App\User');
}
public function postCategories()
{
return $this->belongsTo('App\PostCategory');
}
Controller
public function getPostCategory($catslug) {
$postCategories = PostCategory::with('posts')
->orderBy('name', 'asc')
->where('catslug', '=', $catslug)
->first();
return view ('articles.category.categoriesposts')->with('postCategories', $postCategories);
}
Route
Route::get('articles/category/{catslug}', [
'uses' => 'ArticlesController#getPostCategory' ,
'as' => 'PostCategory'
] );
View
#foreach($postCategories->posts as $post)
<h4>{{ substr($post->title, 0, 50) }}</h4>
<p>{{ substr($post->body, 0, 90) }}</p>
#endforeach
When i use id there is no problem i cant see what i am doing wrong any feedback will be truly appreciated
Thanks
Ash
Save category id in posts table insted of category name or slug.
Change in post category model:
public function posts()
{
return $this->hasMany('App\Post', 'category_id');
}
Your controller method:
public function getPostCategory($catslug)
{
$postCategories = PostCategory::with('posts')->where('catslug', $catslug)->first();
return view('articles.category.categoriesposts')->with('postCategories', $postCategories);
}
If you want to order posts by name then add orderBy() in relationship :
public function posts()
{
return $this->hasMany('App\Post', 'category_id')->orderBy('name', 'asc');
}

Access user's properties (with pivot table) laravel 5.1

I have a users table. The user has possibility to upload a post. The post is saved well to the database. The users can follow each other - so on a pivot table each follower_id has followees_id.
I need to get the posts of the current user followee's . I am kinda messed with getting it from a pivot table.
Here's my code so far:
controller:
protected function get_followee_posts($followee_posts) ////$followee_posts passed from the route.
{
$user = $this->user;
$user->followee()->attach($followee_posts);
$followee_posts = User::find($followee_posts);
}
view:
<div class="following_posts">
<p> Posts from people you're following: <p>
#foreach ($user->follower_id->followee_id->posts as $post)
<form action="/html/tags/html_form_tag_action.cfm" method="post">
<textarea name="comments" id="comments" style="width:96%;height:90px;background-color:white;color:black;border:none;padding:2%;font:22px/30px sans-serif;">
{!! $posts->full_post !!} </textarea>
</form>
#endforeach
route:
Route::get('hub/{followee_posts}','HubController#get_followee_posts')->name('followee_posts');
I am getting an error with the current code saying:
ErrorException in 7340f90cc5faf1a298fcc646b7248b22 line 105:
Trying to get property of non-object
Any help would be lovely. Thank you.
Your not too specific about your schema, but this is how I would go about it.
User Model
class User extends Model
{
protected $table = 'users';
public function posts()
{
return $this->hasMany('Post');
}
public function followers()
{
return $this->hasMany('Follower');
}
}
Follower Model
class Follower extends Model
{
protected $table = 'followers';
public function user()
{
return $this->belongs_to('User');
}
public function posts()
{
return $this->hasMany('Post', 'user_id', 'follower_id');
}
}
Post Model
class Post extends Model
{
protected $table = 'posts';
public function user()
{
return $this->belongs_to('User');
}
}
The followers table would look something like this:
user_id
follower_id
You could then use eloquent method chains to get the posts of a users followers:
// Get Users object with followers and followers posts
// We use with() to eager load relationships
$user = User::with('followers.posts')->find(2);
// Return associative array of post objects
$postsArray = $user->followers->lists('posts');
// Combine posts into a single collection
$posts = (new \Illuminate\Support\Collection($postsArray))->collapse()->toArray();
print_r($posts);

Resources