I am updating my php PDO website using Laravel Framework 5.3. I am finding Laravel very easy to use but there are few functions that I don't know the syntax to achieve results.
I have a Laravel controller
public function index(){
$posts = Post::latest()->get();
return view('/home', compact('posts'));
}
which I use in the blade to fetch data using a foreach loop
#foreach ($posts as $row)
#endforeach
which is similar to fetchAll() method in PDO
$row = $posts->fetchAll();
now I want the logic to get fetch(PDO::FETCH_ASSOC) like result, so that I can assign
$row = $posts->fetch(PDO::FETCH_ASSOC);
I have to do this because I want to use for loop in the blade to show the data, if I use foreach loop then it creates duplication for iterated result. Following is the PDO code that I have to update with Laravel
for($i=0; $i<$count_photos; $i++){
$row_gallery = $get_photos->fetch(PDO::FETCH_ASSOC);
$pst_id = $row_gallery['post_id'];
$img = $row_gallery['img_name'];
echo '<div class="img_gallery"><div class="gallery'.$i.'"> <img class="img-responsive" src="uploads/'. $img . '"></div></div>';
}
The models will have already been fetched when you use get() so you'll be able to access the properties on the model straight away e.g.
#foreach ($posts as $post)
{{ $post->title }} //assuming you have a "title" column in the database
#endforeach
You might find this helpful: https://laracasts.com/series/laravel-from-scratch-2017/episodes/7
Edit
If you have the photos relationship set up in your Post model then you can eager load the relationship. Also, since you only want to load one post you can use first() instead of get() so you would end up with the following:
Controller:
public function index()
{
$post = Post::with('photos')->latest()->first();
return view('/home', compact('post'));
}
Blade file
#foreach($post->photos as $k => $photo)
<div class="img_gallery">
<div class="gallery{{ $k }}">
<a href="{{ url('uploads/'.$photo->img_name) }}" data-lightbox="{{ $post->id }}">
<img class="img-responsive" src="{{ url('uploads/'.$photo->img_name) }}">
</a>
</div>
</div>
#endforeach
Related
firstly, i'm a newbie in laravel.
i insert a array data as a string in server.
column name "category_id" & value like "1,2,3,4".
Now i just want to show these id's category name with eloquent relationship.
Using laravel latest version.
view page
{{$category_var = explode(',',$post->category_id)}}
#foreach($category_var as $category)
#if($category)
<span class="badge mb-3">{{$post->category->category}} </span>
#endif
#endforeach
class page
public function category(){
return $this-> belongsTo(Category::class);
}
Controller page
public function index()
{
$posts = post::paginate(9);
return view('pages/home',compact('posts'));
}
anything else need just ask me.
Thanks
just use the benefits of models and relation like below:
#foreach($posts as $post)
#foreach($post->category as $category)
<span class="badge mb-3">
{{ $category->(what ever you want from category model) }}
</span>
#endforeach
#endforeach
I have the model that has relation to itself like this
public function children() {
return $this->hasMany(AppointmentPart::class,'parent_id');
}
I want to eager loading for queries for this model but because every row can have child with() method doesn't work for me
$parts = AppointmentPart::whereParentId(0)->with('children')->get();
my blade:
<ul id="treeData">
#foreach($parts as $part)
<li id="{{ $part->id }}"
#if(!empty($part->children)) class="folder" #endif>
{{ $part->title }}
#if(!empty($part->children))
#include('appointment::admin.appointment.layout._part_child', array('parts' => $part->children))
#endif
</li>
#endforeach
</ul>
content of _part_child :
<ul>
#foreach($parts as $part)
<li id="{{ $part->id }}" #if(!empty($part->children)) class="folder" #endif>
{{ $part->title }}
#include('appointment::admin.appointment.layout._part_child',['parts'=>$part->children])
</li>
#endforeach
</ul>
how can I do this?
You should use a whereHas() function. Have a look at the official documentation.
If you need even more power, you may use the whereHas and orWhereHas methods to put "where" conditions on your has queries. These methods allow you to add customized constraints to a relationship constraint [...]
So in your case you have to change your method as follows:
$parts = AppointmentPart::with('children')->whereHas('children', function($query) use ($parent_id) {
$query->where('parent_id', '=', $parent_id);
})->get();
you can also create a local scope in order to create a reusable query statement.
This is an example for you. This might help to solve your problem. I have Structure Model which contain organizational structure of a company.
In my StructureController.php
public function index()
{
$parentStructures = Structure::where('parent_id', 0)->get();
return view('structure.structureTreeview', compact('parentStructures'));
}
In my Structure.php, I add with() at the relationship for eager loading.
public function children()
{
return $this->hasMany(Structure::class, 'parent_id')->with('children');
}
And, if you you check with this package here , it won't show any warning.
Reference : check this website here
Just an example:
let's say I have Post model, and the Comment model. Post, of course, have Comments, one-to-many relation.
I have to display list of posts with comments below it.
I'll get my posts in the controller:
$posts = Post::get(), I'll pass it to the blade view and then I'll loop through it
#foreach($posts as $post)
{{ $post->title }}
{{ $post->comments }}
#endforeach
where $post->comments is some relation
public function comments()
{
return $this->hasMany(Comment::class);
}
As we know, that query will be executed many times.
Now my question: how we should optimize it?
Return Cache::remember in the getter?
Get (somehow?) those comments, when getting the posts in one query? Something like join query? I know that I can write that kind of query, but I'm talking about Eloquent's query builder. And then how get the comments within the loop? Wouldn't {{ $post->comments }} call the relation again instead of getting stored data?
Different solution?
You can do $posts = Post::with('comments')->get() to eager load the comments with the post. Read more about it in the documentation: https://laravel.com/docs/5.7/eloquent-relationships#eager-loading
Also, to display the comments you would want to add another foreach loop. It would look something like this:
#foreach($posts as $post)
{{ $post->title }}
#foreach($post->comments as $comment)
{{ $comment->title }}
#endforeach
#endforeach
You’ve probably cached some model data in the controller before, but I am going to show you a Laravel model caching technique that’s a little more granular using Active Record models
Note that we could also use the Cache::rememberForever() method and rely on our caching mechanism’s garbage collection to remove stale keys. I’ve set a timer so that the cache will be hit most of the time, with a fresh cache every fifteen minutes.
The cacheKey() method needs to make the model unique, and invalidate the cache when the model is updated. Here’s my cacheKey implementation:
public function cacheKey()
{
return sprintf(
"%s/%s-%s",
$this->getTable(),
$this->getKey(),
$this->updated_at->timestamp
);
}
public function comments()
{
return $this->hasMany(Comment::class);
}
public function getCachedCommentsCountAttribute()
{
return Cache::remember($this->cacheKey() . ':comments_count', 15, function () {
return $this->comments->count();
});
}
yes u can do like that in controller
$minutes = 60;
$posts = Cache::remember('posts', $minutes, function () {
return Post::with('comments')->get()
});
in blade u can get like that
#foreach($posts as $post)
{{ $post->title }}
#foreach($post->comments as $comment)
{{ $comment->title }}
#endforeach
#endforeach
for more information read this article
I've got a Laravel project where you can create articles and so on. Of course I want to have an image slideshow with multiple images per article. I've managed to save multiple images in the database in one column via implode. PICTURE
How do I display the slideshow now? I have no idea.
The short answer is the one #Sang Nguyen posted: The opposite of implode() is explode().
However I am going to add a more "Laravel-like" way of doing it:
Assuming you have an Article model, add an accessor:
class Article extends Model {
...
public function getImagesListAttribute() {
return collect(explode('|', $this->images));
}
...
}
Then:
$article = Article::find(1);
var_dump($article->images_list); //would be a Collection of strings (which are your image names)
More about accessors: https://laravel.com/docs/5.6/eloquent-mutators#defining-an-accessor
More about collections: https://laravel.com/docs/5.6/collections
You just need to explode your data from database then show it
$images = explode('|', $post->image);
#foreach ($images as $image)
<img src="{{ url($image) }} alt="image" />
#endforeach
Then you can use OwlCarousel https://owlcarousel2.github.io/OwlCarousel2/ to create slideshow.
You can create a basic slider with this example https://owlcarousel2.github.io/OwlCarousel2/demos/basic.html
Example: In your blade view
<div class="owl-carousel owl-theme">
#foreach (explode('|', $post->image) as $image)
<div class="item"><img src="{{ url($image) }} alt="image" /></div>
#endforeach
</div>
so i want to display post in my index page but only the posts that are reviewed by the admin. so i added another column in my database table post which is called "review" which is integer. So this is what i have in hand.
in my controller i have this
public function index()
{
$this->layout->content = View::make('partials.index',
array(
'posts' => Post::paginate(9)
));
}
and in my index page i have this
#section('content')
<div class="dashboard">
#foreach (array_chunk($posts->getCollection()->all(),2) as $row)
<div class="row">
#foreach($row as $post)
<article class="col-md-4 effect4" id="dash-box">
<p></p>
<c>{{$post->content}}</c><br>
<b>{{$post->title}}</b><br>
<d>posted..{{$post->created_at->diffForHumans()}}</d>
<hr>
</article>
#endforeach
</div>
#endforeach
<div class="page">
{{$posts->appends(Request::only('difficulty'))->links()}}
</div>
</div>
#stop
Help im newbie here i hope someone can help me out with this one hoping for a reply thanks
Just call:
Post::whereReview(1)->paginate(9);
Please read the documentation (and also the one for the query builder since these pages apply to Eloquent as well)
You can just add a where() call to the query:
$posts = Post::where('review', '=', 1)->paginate(9);
Or a shorter version (= is the default operator)
$posts = Post::where('review', 1)->paginate(9);
Or even with a dynamic method name:
$posts = Post::whereReview(1)->paginate(9);
Also you can use true instead of 1. Laravel will convert it:
$posts = Post::whereReview(true)->paginate(9);
There is also no need to do chunking that complicated:
#foreach (array_chunk($posts->getCollection()->all(),2) as $row)
You can just use the chunk method on any collection:
#foreach ($posts->chunk(2) as $row)