I'm trying to make a RBAC in my own forum software.
For so far, the permissions work, but the problem is, when I want to add colors to usernames (what MyBB also has) something doesn't work and I don't understand it propperly.
So I have an ForumController with this code inside:
<?php
class ForumController extends \BaseController {
public function index()
{
$forums = Forums::orderBy('disp_order', 'asc')->get();
$categories = Categorie::orderBy('disp_order', 'asc')->get();
return View::make('index')->with('forums', $forums)->with('categories', $categories);
}
public function forum($name)
{
$forums = Forums::where('name', '=', str_replace('Forum-', '',str_replace('-', ' ', $name)))->first();
$categories = Categorie::orderBy('disp_order', 'asc')->get();
return View::make('forum')->with('forums', $forums)->with('categories', $categories);
}
public function categorie($name)
{
$categories = Categorie::where('name', '=', str_replace('Categorie-', '',str_replace('-', ' ', $name)))->first();
$threads = Thread::orderBy('date_posted', 'asc')->get();
return View::make('categorie')->with('categories', $categories)->with('threads', $threads);
}
public function thread($title)
{
$thread = Thread::where('title', '=', str_replace('Thread-', '',str_replace('-', ' ', $title)))->first();
$comments = Comment::orderBy('posted_at', 'asc')->get();
return View::make('thread')->with('threads', $thread)->with('comments', $comments);
}
}
Good, everything of that works.
But now I need to get the roles for users inside of the function thread.
I also have these models:
There is only an extend to Eloquent and the protected $table inside of these files.
The scheme of my role table looks like this:
I did hear somethig about belongsTo and hasMany, but I really don't understand it...
I want to be able to get the right color on the right user.
So the scheme of the user table:
I hope someone can help me out, because I'm looking for the answer a long time.
I'm using Laravel4
Kindest regards,
Robin
You're right, you need to add some relationships:
// In Comment.php, assuming that your comments table has a user_id field.
public function user()
{
return $this->belongsTo(User::class);
}
// In User.php
public function role()
{
return $this->belongsTo(Role::class);
}
Then adjust your controller to eager load these relationships.
$comments = Comment::orderBy('posted_at')->with('user.role')->get();
Now you can show the color next to a comment in your blade template like:
#foreach ($comments as $comment)
<p>Color: {{ $comment->user->role->colour }}</p>
#endfoeach
Related
Hellow guys,
so I have 2 tables
is Listings
is Users
in Listings I have some columns, one is user_id, and is related to users tables.
I want to display the user name related to the user table.
in the index blade, I use some tags.
But when I use ->rightjoin("users", "users.id", "=", "listings.user_id") it's works but,
the join broke my tags make them default, same with others posts.
public function index(Request $request)
{
$listings = Listing::where('is_active', true)->with('tags')
//->rightjoin("users", "users.id", "=", "listings.user_id") //don't show tags of the posts
->orderBy('listings.created_at', 'desc')
->get();
//check if posts ar listing by last date or something
$tags = Tag::orderBy('name') // variable displayed in view
->get();
You could just use the with method to get the related user like this
public function index(Request $request) {
$listings = Listing::where('is_active', true)->with(['user', 'tags'])
->orderBy('listings.created_at', 'desc')
->get();
}
but make sure that you add to your Listing model the correct relation like this
Listing Model
public function user() {
return $this->belongsTo(User::class);
}
I recommend this code for controller:
public function index(Request $request) {
return $listings = Listing::query()
->where('is_active', true)->with(['user', 'tags'])
->orderBy('listings.created_at', 'desc')
->get();
}
In the models section, I suggest you put this code:
public function user() {
return $this->belongsTo(User::class);
}
I suggest you fill in the fields foreignKey, ownerkey in relation: as in the following example:
public function user()
{
return $this->belongsTo(User::class, 'user_id', 'id');
}
I have implemented eloquent relationship in my code but Laravel unable to read the function that I created to map the eloquent relationship in the model.
User Model
public function products(){
return $this->hasMany(Product::class,'userid');
}
Product Model
public function users(){
return $this->belongsTo(User::class);
}
Product Controller
$products = Product::with('Users')->Users()->where('users.isActive',1)->get();
return view('product',compact('products'));
I keep getting error from the product controller, I also attached the error that I current encountered as below.
How can I get all the product and user data with the where condition such as "Users.isActive = 1".
Thanks.
You can use whereHas to filter from a relationship.
$products = Product::with('users')
->whereHas('users', function ($query) {
$query->where('isActive', 1);
})
->get();
Also it is generally a good idea to use singular noun for belongsTo relationship because it returns an object, not a collection.
public function user() {
return $this->belongsTo(User::class);
}
$products = Product::with('user')
->whereHas('user', function ($query) {
$query->where('isActive', 1);
})
->get();
EDIT
If you want to retrieve users with products you should query with User model.
$users = User::with('products')
->where('isActive', 1)
->get();
Then you can retrieve both users and products by
foreach($users as $user) {
$user->products;
// or
foreach($users->products as $product) {
$product;
}
}
You can use whereHas() method for this purpose. Here is the doc
$products = Product::with('users')->whereHas('users', function (Illuminate\Database\Eloquent\Builder $query) {
$query->where('isActive', 1);
})->get();
$users = $products->pluck('users');
return view('product',compact('products'));
You have a typo after the with, is users instead of Users and you're redundant about the Query Builder, remove the ->Users():
Before:
$products = Product::with('Users')->Users()->where('users.isActive',1)->get();
return view('product',compact('products'));
After:
$products = Product::with('users')->where('users.isActive',1)->get();
return view('product',compact('products'));
Fix that and all should work.
I have a blog and want to include the Users Name when shown to the public.
When creating the blog I make sure to include the user_id in the blogs table
In my Blog model I have the following:
public function users()
{
return $this->belongsTo(User::class);
}
In my Users model I have:
public function blogs()
{
return $this->hasMany(Blog::class);
}
In my Blog Controller I have:
public function index(User $user)
{
$users = User::get();
$blogs= DB::table('blogs')->where('user_id', '=', $users->id)->orderBy('id', 'DESC')->paginate(6);
return view('blogs.index',compact('blogs'));
}
Then in my view:
#foreach($blogs as $blog)
<h1>{{$blog->title}}</h1>
Source:{{$blog->users->first_name}} // This does not work
Source:{{$blog->first_name}} // This does not work either
#endforeach
I thought I could do something like this to show the names:
{{ $blogs->users->first_name }} {{ $blogs->users->last_name }}
But this isn't working either...
Try this:
#foreach($blogs as $blog)
<h1>{{$blog->title}}</h1>
{{$blog->user->first_name}}
#endforeach
And on your Blog Model
public function user()
{
return $this->belongsTo(User::class);
}
In your Blog controller the variable $blog needs to be $blogs. You also have extra characters (right parenthesis) in your Blade. It should be:
#foreach($blogs as $blog)
Source: {{ $blog->user->first_name }}
...
#endforeach
Blog Model
This function replaces the old "users" function, as only one user is returned (belongsTo is a singular relationship).
class Blog extends Model
{
public function user()
{
return $this->belongsTo('App\User');
}
}
User Model
public function blogs()
{
return $this->hasMany('App\Blog');
}
Controller Function
And, as such, you can cut down your controller code, including removing the redundant elements.
public function index(User $user)
{
$blogs = Blog::where('user_id', '=', $user->id)->orderBy('created_at','desc')->paginate(6);
return view('blogs.index', compact('blogs'));
}
The way you did is called Query Builder
$blogs= DB::table('blogs')->where('user_id', '=', $users->id)->orderBy('id', 'DESC')->paginate(6);
Query Builder does not support lazy loading, cause lazy loading is only supported for the Eloquent method
$blog->users->first_name
For Eloquent way you can try this instead:
$blogs = Blog::where('user_id', $user->id)->get()
foreach($blogs as $blog){
dd($blog->user); // you will get the user detail here
}
For lazy loading have a performance issue when come to load heavy data so to prevent lazy loading can use this
$blogs = Blog::with('user')->where('user_id', $user->id)->get()
For more information can look at Eloquent Relationship Documentation
For query builder, the only way to link your user is use join, which will be something like this
$blogs = DB::table('blogs')
->join('users', 'users.id', '=', 'blogs.user_id')
->get();
foreach($blogs as $blog){
dd($blog->first_name) // user first name
}
For more information can look at Query Builder Join
BlogController.php
public function index(){
$blogs = Blog::with('user')->get();
return view('blogs.index')->with('blogs',$blogs);
}
Blog.php
public function user()
{
return $this->belongsTo('App\User');
}
User.php
public function blogs()
{
return $this->hasMany('App\Blog');
}
In my routes/web.php I have a route like this...
Route::get('/tags/{tag}', 'TagsController#show');
Then, inside TagsController because I have a post_tag pivot table that has been defined as a many-to-many relationship.
Tag.php...
public function posts(){
return $this->belongsToMany(Post::class);
}
public function getRouteKeyName(){
return 'name';
}
Post.php...
public function tags(){
return $this->belongsToMany(Tag::class);
}
I get the posts for a certain tag like this...
public function show(Tag $tag){
$posts = $tag->posts;
return view('posts.index', compact('posts','tag'));
}
Then, to sort the posts into newest first I can do this in index.blade.php...
#foreach ($posts->sortByDesc('created_at') as $post)
#include('posts.post')
#endforeach
This works fine, but I'm doing the re-ordering at collection level when I'd prefer to do it at query level.
From Eloquent: Relationships I can see that I can do something like this, which also works...
$user = App\User::find(1);
foreach ($user->roles as $role) {
//
}
But, something like this does not seem to work...
public function show($tag){
$posts = \App\Tag::find($tag);
return view('posts.index', compact('posts'));
}
My question is, how can I filter/order the data at a query level when using pivot tables?
To order your collection you must change
public function tags(){
return $this->belongsToMany(Tag::class);
}
to
public function tags(){
return $this->belongsToMany(Tag::class)->orderBy('created_at');
}
Extending #leli. 1337 answer
To order content without changing the relation created.
First, keep the original relation
class User
{
public function tags
{
return $this->belongsToMany(Tag::class);
}
}
Second, during query building do the following
//say you are doing query building
$users = User::with([
'tags' => function($query) {
$query->orderBy('tags.created_at','desc');
}
])->get();
With this, you can order the content of tags data and in query level also if needed you can add more where clauses to the tags table query builder.
Im new in Laravel 4, and right now im coding for small project, i use laravel as framework to build my website, but my code i always wonder it's optimize or not because in my model i just wrote:
Category Model
public function parents()
{
return $this->belongsTo('Category', 'cat_father');
}
public function children()
{
return $this->hasMany('Category', 'cat_father');
}
}
Post Model:
<?php
class Post extends BaseModel{
public $table = "post";
protected $primaryKey = 'idpost';
public function Category()
{
return $this->belongsTo('Category', 'cat_id');
}
}
because i didn't know how to join 2 tables in laravel 4, i have a condition is find all post from my categories, which it hadn't belong to category name "Reunion", but i didn't know how to do that, therefore i wrote 2 lines code for that purpose (im not sure wrote code in controller is best way but i didn't know how to call method from Model to controller and get return value)
My method from controller for select all post, it hasn't belong to category name "Reunion"
public function getAllPostView()
{
$getCat = Category::where('cat_name','=', 'Reunion')->firstOrFail();
$post = Post::where('cat_id', '!=', $getCat->idcategory)->get();
return View::make('layouts.post')->with('post',$post);
}
My question, my code is optimize when i wrote it in controller? and how to wrote it in model and get parameter for passing it to controller and use it to view.
second question is how to order "POST" because some cases post need to be ordered from new to old
This is how you do it:
$exclude = 'Reunion';
$posts = Post::select('posts.*')->join('categories', function ($j) use ($exclude) {
$j->on('posts.cat_id', '=', 'categories.idcategory')
->where('categories.name', '<>', $exclude);
})->get();
could just use simple joins
public function getAllPostView()
{
$getCat = Category::where('cat_name','=', 'Reunion')
->join('post','post.cat_id', '!=','Category.idcategory')->get();
return View::make('layouts.post')->with('post',$post);
}
Look out for same field names in both the tables if so can use select
$getCat = Category::select('Category.idcategory as cat_id','Category.cat_id as pos_id','many other fields')
// 'as cat_id' not required for unique field names
->join('post','post.cat_id', '!=','Category.idcategory')
->where('cat_name','=', 'Reunion')
->get();