Laravel 5.8 Eloquent querying - php

I know all the Eloquent model querying is in the Laravel documentation and I have read through them to figure this out but can't seem to work my way around it. I am building a recipe application, and I want to get access to a particular profile picture of a user based on an uploaded recipe.
I have a grid of recipes that have been uploaded by various users. The User and Recipe model are below.
User Model
public function recipes()
{
return $this->hasMany('App\Recipe');
}
Recipe Model
public function user()
{
return $this->belongsTo('App\User');
}
In my recipe grid, I have the following code in a recipe card.
Index Blade/View
#foreach($recipes as $recipe)
<img class="recipeProfilePic" src="/storage/profile_pictures/{{What goes here}}" alt=""><a
href="{{ route('user', $recipe->user_id) }}">
<small>{{$recipe->author}}</small>
</a>
#endforeach
Through the $recipe I can access the name of the creator of that particular recipe like this $recipe->author. I am trying to get access to this specific users profile photo too. I want to get something like this $recipe->author->profile_pic. (profile_pic is a column in my users table).
How would I go about solving this problem in a simple way? I'm a newcomer to coding and am still working on solving these problems myself. Thank you!

You can do it like this:
$recipe->user->profile_pic

You can change the model by rename user to author like this:
public function author()
{
return $this->belongsTo('App\User');
}
or changing view (blade) like this:
#foreach($recipes as $recipe)
<img class="recipeProfilePic" src="/storage/profile_pictures/{{What goes here}}" alt=""><a
href="{{ route('user', $recipe->user_id) }}">
<small>{{$recipe->user->profile_pic}}</small>
</a>
#endforeach

Related

better understanding about #foreach on laravel

i just want to ask how exactly #foreach in laravel works for examply code like this
#foreach ($users as $user)
#endforeach
i know $users value can be obtained from controller like this:
public function show()
{
$users = users:find($id);
return view('user_tab', compact('users'));
}
but i saw some tutorial on site that do #foreach like :
#foreach ($user->posts as $post)
#endforeach
what's posts without $ stand for ?? i just dont know. i do already read laravel documentation about this on here https://laravel.com/docs/8.x/blade but still cant understand it can someone explain it to me? thx for advance
$user->posts
Here 'posts' represents a model relationship. Go to your User model and you will find a function like this:
function posts() {
return $this->hasMany(Posts::class);
}
This represents that a User can have multiple posts. You can directly get all the post of an user by calling this function once you get a user instance.
Hence in your code it is fetching all the posts of the specific user by $user->posts and then iterating over it in #foreach loop.
if in your controller you call user with relation then you can access the related enter code here` like this

Random images in laravel

I have a database table called random_img. Inside are 10 rows for 10 images.
I will be pulling the images from public/images/random
I want to use the database so I can set the loop to Random take(1). I want to use in my hero images. (New image on every page refresh)
Where would I put my database query so I can use it Globally? Or how can I use my RandomImgsController so it is being used globally?
I created a route file, so I can use it as an include where needed.
Route:
Route::post('/layouts/inc/random-img','RandomImgsController#randomimg')->name('random-img');
Include:
#include('layouts.inc.random-img')
Inside Include:
#foreach ($randomimg as $rand)
<span class="hero-image">
<img src="/images/random/{{$rand->file_name}}" class="img--max--hero blur-img">
</span>
#endforeach
RandomImgsController: (Where should this go so I can use globally)
public function randomimg()
{
$randomimg = DB::table('randomimg')->orderBy(DB::raw('RAND()'))->get();
return view('random-img',compact('randomimg'));
}}
This is what I want to achieve on every page of my website:
#php
$randomimg = DB::table('randomimg')->orderBy(DB::raw('RAND()'))->get()->take(1);
#endphp
#foreach ($randomimg as $rand)
<span class="hero-image">
<img src="/images/random/{{$rand->file_name}}" class="img--max--hero blur-img">
</span>
#endforeach
What would be a cleaner way to do this?
Update:
I can access the images DB in all views now, but I have an issue.
In my App\Http\ViewComposer\ImageComposer.php file I have this:
public function compose(View $view)
{
$view->with('foo', Image::inRandomOrder()->get()->take(1));
}
In any view I can use {{$foo}} to get a random row from my images table, but the data comes in a string like this:
[{"id":10,"alt":"Image Alt Tag","title":"Image Title","file_name":"10.jpg"}]
When I try to only grab individual columns like this {{$foo->file_name}}
I get the error:
Property [file_name] does not exist on this collection instance.
How can I grab individual columns like this: {{$foo->alt}} , {{$foo->title}} and {{$foo->file_name}} then cleanly output them in my view? Example, I need {{$foo->file_name}} to render like this: 5.jpg.
Update 2:
I figured it out. Have to use #foreach since I'm using the get() method.
#foreach($foo as $f)
{{$f->file_name}}
#endforeach
Would still like to know if there is a way to do it without the get() method. This will work though.
First of all you can't #include a route in a blade template. What you would actually do is send an AJAX request from your blade template to the route you created to retrieve the random images. However...
It sounds like a controller is the wrong place for the logic in this situation.
Assuming you have an associated Eloquent model for your table, a simple option could be to define a method on your RandomImage model (could probably just be called Image).
This way, you can just use your Image model to generate and pass a random image to any view you would like. Then there is also no need to query for every image on each page reload. You would only ever be querying for one image per request.
Imagine if the code in your view could look like this:
<span class="hero-image">
<img
src="{{ $image->url() }}"
class="img--max--hero blur-img" />
</span>
And maybe this belongs in a home page for example, which is what it sounds like you're trying to do. So maybe you have a route like this:
Route::get('/', function () {
$image = App\Image::random();
return view('home', compact('image');
});
You could achieve this using a Query Scope on your Image model:
public function scopeRandom($query)
{
return $query->inRandomOrder()->first();
}
Edit
If you want this to be used across many, or even all views in your website you can use a View Composer: https://laravel.com/docs/5.6/views#view-composers
Your compose method would look like this:
public function compose(View $view)
{
$view->with('image', Image::random());
}
And the View Composer would be registered either in your AppServiceProvider or in a new provider such as ComposerServiceProvider. Inside of the boot method you need:
public function boot()
{
// Using class based composers...
View::composer(
'*', 'App\Http\ViewComposers\ImageComposer'
);
}
Where the * says that you want this composer to be applied to all views.

laravel Eloquent: Relationships get third part relation

iam working in journal project and i have 3 main table related
Volumes->issues->articles
volume has many issue but issue has one volume
issues has many articles but article has one issue
all working fine but i have 1 tricky step
i want to get volume name when view all articles. i want view the following when retrieving articles
article name | vol name/issue name
i success to get issue name as i have relation between article module and issue module but i dont know how to get volume name inside for-each articles
<tr>
<th>Title</th>
<th>Vol/Issue</th>
</tr>
#foreach($articles as $article)
<td>{{ $article->title }}
<td>{{ ??? }} / {{$article->issue->name}}</td>
#endforeach
Assuming you have the belongs to relations set up in each model to act as the reverse of your has many relations:
class Article extends Model
{
public function issue()
{
return $this->belongsTo(Issue::class);
}
}
class Issue extends Model
{
public function volume()
{
return $this->belongsTo(Volume::class);
}
}
You should be able to eager load the issue relation and the issue's volume relation when retrieving your articles, like this:
$articles = Article::with(['issue', 'issue.volume'])->get();
and in your view (Assuming you use the name attribute):
{{ $article->issue->volume->name }}
For more information regarding this, look up "Nested Eager Loading" in the documentation

Laratrust : Users and Roles Usage

I'm a Laravel user. I am currently trying to use the Laratrust package for web admin purposes. For User and Role implementations I want one user to hold multiple roles and one role many users can have. In my opinion, the most suitable relationship is Many to Many Relationship, am I correct? Then, is the function I made right?
App\User;
public function roles()
{
return $this->belongsToMany('App\Role');
}
App\Role;
public function users()
{
return $this->belongsToMany('App\User');
}
Then how do I display the two interconnected data in one blade file? Thanks.
Define relations as users() and roles(). You can display all roles of the user with something like this:
#foreach ($user->roles as $role)
{{ $role->name }}
#endforeach

Setting anchor link to an address in Laravel, gives error

In my Laravel application, when I am trying to link the username of the person who has posted in the website with his profile page, with the code:
<div class="media-body">#{{ post.user.name }}
It is giving the error:
Sorry, the page you are looking for could not be found.
1/1 NotFoundHttpException in RouteCollection.php line 161:
But, when I am trying to print #{{ post.user.profileUrl }} it is giving the right address, also in the json response, it is giving the right address, and going to the address is also reaching the specific location.
So, I don’t think it is some problem with post.user.profileUrl, as it seems to work fine, it seems to be some problem with using it with href, the address of the error in Google Chrome is:
http://localhost:8000/%7B%7B%20post.user.profileUrl%20%7D%7D
and the address should have been
http://localhost:8000/users/2 where 2 refers to the id of the user, which I am passing to the user through Vue.js
The problem is #{{ post.user.profileUrl }} is not parsing. %7B%7B%20post.user.profileUrl%20%7D%7D is ASCII representation of {{ post.user.profileUrl }}
Check if the code is in .blade.php file. If it is, you should look into JS template engine if you're using any.
https://laravel.com/docs/5.3/blade#blade-and-javascript-frameworks
The # symbol will be removed by Blade; however, {{ name }} expression will remain untouched by the Blade engine, allowing it to instead be rendered by your JavaScript framework
I think you have a $post model in your view. When you setup relationships between the model Post and User you can link to them through the following:
#{{ $post->user->name }}
This will turn the users profileUrl into a valid link. But therefor you had to setup relationships in the Models.
Post model:
public function user() {
return $this->hasMany('App\Users', 'id', 'user_id');
//first parameter is the Model class
//send is the id of the user table
//thirth is the user_id in the post table
}
And in the User model:
public function posts() {
return $this->hasMany('App\Posts', 'user_id', 'id');
}
Hope this works!
Try this... this should definitely work for you
#verbatim
<div class="media-body">
<a href="{{ post.user.profileUrl }}">
{{ post.user.name }}
</a>
</div>
#endverbatim
I got my problem, the issue is with the javascript library, I am using, known as vue.js, it used to allow usage inside quotes, but in vue 2, they don't, so there is a turnaround for this,
<a :href="post.user.profileUrl">#{{ post.user.name }}</a>
and this works fine.
Thanks to all the people who contributed by answering...

Categories