Laravel 4 - Linking posts to the appropriate subject - php

I'm stuck trying to figure out how to get my posts to display under the same subject. I'm currently porting over procedural code where posts have a subject_id that linked to the subject id in the db.
Example:
Subject 1
Related post 1
Related post 2
Subject 2
Related post 1
Related post 2
The area I don't understand fully comprehend after looking at similar Stack posts is where the subject/post are connected in the model. Right now the code is just showing all subjects and posts but not displaying the posts assigned to the same subject.
Help in understanding what I am doing wrong would be appreciated. Thanks.
Controller
public function index()
{
// Get all subjects
$subjects = Subjects::all();
// $subjects = Subjects::with('pages')->get();
$pages = Pages::all();
// Load the view and pass in the subjects
// return View::make('index')->with('subjects', $subjects)->with('pages', $pages);
return View::make('index', compact('subjects', 'pages'));
}
Subjects Model
class Subjects extends Eloquent {
public function pages ()
{
return $this->hasMany('Pages', 'subject_id');
}
}
Posts Model
class Pages extends Eloquent {
public function subjects ()
{
return $this->belongsTo('Subjects', 'id');
}
}
View
#foreach ($subjects as $subject)
<tr>
<td> {{ $subject->menu_name }} </td><br>
</tr>
#foreach ($pages as $page_id)
<tr>
<li>{{ $page_id->menu_name }}</li><br>
</tr>
#endforeach
#endforeach

You can load each subject's pages by calling $subject->pages in your loop:
Controller:
public function index()
{
return View::make('index')->withSubjects( Subjects::with('Pages')->get() );
}
Note: For efficiency, we're calling with('Pages') in the controller, to eager load the pages.
View:
#foreach ($subjects as $subject)
<tr>
<td> {{ $subject->menu_name }} </td>
</tr>
#foreach ($subject->pages as $page)
<tr>
<li>{{ $page->menu_name }}</li>
</tr>
#endforeach
#endforeach

Related

How can I get field_name from the first table using relationship between two models using laravel 6?

I have two tables with two models and make a reactionship to can get the field_name from the first table :-
First Model:
class KpcField extends Model
{
public function concession(){
return $this->hasMany(Concessions::class);
}
}
Second Model :
class Concessions extends Model
{
public function kpcField(){
return $this->belongsTo(KpcField::class);
}
}
And trying to retreive the field_name in concession view but it showed (Trying to get property field_name of non-object)
Using the foreach to show the data in table :
#foreach ($show_concessions as $show_concession)
<td> {{ $show_concession->kpcField->field_name}} </td>
#endforeach
You can Try This :
#foreach ($show_concessions as $show_concession)
#foreach ($show_concession->kpcField as $item)
<td> {{ $item->field_name}} </td>
#endforeach
#endforeach

How to use pagination along with laravel eloquent find method in laravel 5.4

I am trying to implement pagination in laravel and got following error
Undefined property: Illuminate\Pagination\LengthAwarePaginator::$name
Here is my controller function
public function showTags($id)
{
$tag = Tag::find($id)->paginate(5);
// when lazy loading
$tag->load(['posts' => function ($q) {
$q->orderBy('id', 'desc');
}]);
return view('blog.showtags')->withTag($tag);
}
Here is the Tag Model
class Tag extends Model
{
public function posts()
{
return $this->belongsToMany('App\Post');
}
}
The Tag and Post model has belongsToMany Relationship so there are many posts under the specific tag and my aim is to iterate all posts under the specific tags descending order of post and also to implement pagination in that page.
Here is the code for showtags view
<table class="table">
<thead>
<tr>
<th>#</th>
<th>Title</th>
<th>Tags</th>
</tr>
</thead>
<tbody>
<?php $count = 1; ?>
#foreach($tag->posts as $post)
<tr>
<th>{{ $count++ }}</th>
<th>{{ $post->title }}</th>
<th>#foreach($post->tags as $tag)
<span class="label label-default">{{ $tag->name }}</span>
#endforeach
</th>
</tr>
#endforeach
</tbody>
</table>
//Here is the code i used for pagination in view
<div class="text-center">
{!! $tag->posts->links() !!}
</div>
If anybody know how to do this please respond. Thanks in advance.
I solve the problem by using a simple trick. My aim was to paginate all posts under the same tags just like you guys can see in StackOverflow.
The modified controller function is
public function showTags($id)
{
$tag = Tag::find($id);
// when lazy loading
$tag->load(['posts' => function ($q) {
$q->orderBy('id', 'desc')->paginate(10);
}]);
return view('blog.showtags')->withTag($tag);
}
As you guys see that I move the paginate() function from find to load function which I use before for sorting post by descending order.
Now in view instead of using traditional method {!! $tag->links() !!} for making link of pagination
I use {!! $tag->paginate(10) !!}
With this line $tag = Tag::find($id)->paginate(5); You should get only one tag(or null if tag with your id dose not exist), and after that you want paginate it. If you want paginate your tags get all tags and after that paginate it Tag::paginate(5)

Laravel Eloquent : belongsTo relationship - Error: Trying to get property of non-object

First time to try laravel eloquent relatioinstip
I know it's really simple but I am getting this error don't know what's wrong with it
I have 2 tables in data base, news and news_image
in database
Tables:
news
id | header | details
news_image
id | image | news_id
And have 2 models News , newsImage
newsImage model :
class newsImage extends Eloquant {
protected $table = 'news_image';
public function news()
{
return $this->belongsTo('News');
}
}
News model
class News extends Eloquent
{
protected $table = 'news';
public $timestamps = false;
public function image()
{
return $this->hasMany('newsImage');
}
}
The view:
foreach($news as $new)
<tr>
<td> {{$new->id}} </td>
<td> {{ $new->header}}</td>
<td> {{ $new->details }}</td>
</td> {{$new->news->image}}</td>
</tr>
when I run this it's get error :
Trying to get property of non-object (View: /var/www/html/clinics/app/views/news/index.blade.php)
Any ideas on what could be causing this error?
First, assuming what you are passing to your view is an array or Collection of News objects, you should probably be using $new->image to access the News Item relation. By defining the function image() in your News model, you can access the relation with either the ->image or ->image() calls. In either case, what you need to call is probably
$new->image->first()->image
To break that down:
->image gets the Collection of NewsImage relations
->first() gets the first item in the Collection
->image (the secone one) gets the image field from that NewsImage
If the Collection has more than one item, you can instead loop over it to get all of the images as shown in the other answer.
There are a couple things I would change:
In your News model, change the relationship from "image" to "images" since it's a one to many relationship. It just keeps your code clean.
Your foreach loop in your view should loop through all the news models, but remember that each news model has multiple images, so you should have another loop inside your existing loop to display the images, i.e. foreach ($new->images as $image)
#foreach ($news as $new)
<tr>
<td> {{$new->id}} </td>
<td> {{ $new->header}}</td>
<td> {{ $new->details }}</td>
<td>
#foreach ($new->images as $image)
{{ $image->image }}
#endforeach
</td>
</tr>
#endforeach

How to use Laravel Pagination with models relationsips?

I have categories and items tables. Each item belongs to only one category and each category has many items. So, in Category model I defined this relationship:
public function items()
{ return $this->hasMany('Item', 'catid'); }
and I retrieve data for a category this way:
$category = Category::find($id);
return View::make('admin.categories.catdetails')->with('category', $category);
and in my view I can loop through data:
#foreach ($category->items as $item)
<tr>
<td> {{ $item->name }} </td>
<td> {{number_format($item->price, 2, '.', '')}} </td>
</tr>
#endforeach
but this results in all items in on page. How to make use of laravel pagination in case that I have so many items for one page??
How can I use
::paginate() // in controller or model
->links() // in view
as, so far, it throws many errors and I can't figure it out.
Thanks in advance.
You can call paginate() on the relationship object, which you access by ->items() (not ->items)
$items = $category->items()->paginate(10);
return View::make('admin.categories.catdetails')
->with('category', $category)
->with('items', $items);
Then in your view:
#foreach ($items as $item)
And:
$items->links()
You could use an attribute accessor to achieve what you want. In your model:
public function getPaginatedItemsAttribute(){
return $this->items()->paginate(10);
}
And then you use it like this:
#foreach ($category->paginatedItems as $item)
And:
$category->paginatedItems->links()

Laravel eloquent - One to many relationships (Trying to get property of non-object)

I have "posts" table that has many-to-one relationship with "categories" table. The goal is to show all of posts and their categories.
Tables:
Posts: id, content, category_id, etc
Categories: id,name
Here's my code
Models:
class Posts extends Eloquent
{
public static $table = 'posts';
public function categories()
{
return $this->belongs_to('Categories');
}
}
class Categories extends Eloquent
{
public static $table = 'categories';
public function posts()
{
return $this->has_many('posts');
}
}
My controller
public function get_posts()
{
$posts = Posts::with('categories')->all();
return View::make('admin.posts')
->with('title', 'Posts')
->with('posts', $posts);
}
My view
#foreach($posts as $post)
<tr>
<td>{{ $post->title }}</td>
<td>{{ $post->categories->name }}</td>
<td><small> {{$post->updated_at}} </small></td>
<td>
<button>
{{HTML::link_to_route('edit_post','Edit',array($post->id))}}
</button>
{{Form::open('admin/delete','Delete')}}
{{Form::hidden('id', $post->id)}}
<input type="submit" name="edit_post" value="Delete"/>
{{Form::close()}}
</td>
</tr>
#endforeach
ERROR:
Error rendering view: [admin.posts]
Trying to get property of non-object
I am a newbie, please help me solve this issues
{{ $post->categories->name }} before test is categories exists
Example:
#if( ! empty($post->categories))
<td>{{ $post->categories->name }}</td>
#else
#end if
Aesis.
Just use ::all() instead of ::with(..)->all()
categories is an array as you are using a has_many relationship. There are many categories, hence an array is returned, so to access it you have to index it like an array
the correct solution would be
$post->categories[0]->name
Are you using Laravel 4? First the syntax for declaring relationship is hasMany and belongsTo, in camel case. Check it out in Laravel documentation
In view, check if categories are empty collection, ie., whether post has its category:
#if($post->categories->count())
<td>{{ $post->categories->name }}</td>
...
#endif
By the way, I would use singular form as model class name, like Post and Category instead of plural forms. And in Post class I would define inverse one-to-many relationship with singular form, to show there's only one entry in category table for this given Post.
public function category()
{
return $this->belongsTo('Category');
}

Categories