Handling Scope with User Role Constraint - Laravel 5.3 - laravel

If you try to look at the role name it doesn't really look good. I know this is not the best way to handle such condition. Is there a better way to do it?
public function scopeWishlist( $query ){
if( Auth::User()->role->name == "admin" || Auth::User()->role->name == "staff"){
return $query->where('transaction_type', '=', 1);
}
}

This is a much cleaner code
public function scopeWishlist($query, $role)
{
$roles = ['admin', 'staff'];
return (in_array($role, $roles)) ? $query->where('transaction_type', 1) : $query;
}
Then you can do something like
Model::where('blahblah', 'blahblah')->wishlist(auth()->user()->role->name)->get();
Hope it helps :)

Related

Return null from eloquent relationship?

I have this relationship in one of my model classes:
public function userLike()
{
if (Auth::check()) return $this->hasOne('App\Like')->where('user_id', Auth::user()->id);
// RETURN NULL IF RECORD DOESN'T EXIST?
}
As you can see, it checks if the user is logged in and returns the Like record. However, how can I return null if the record doesn't exist?
I tried this:
public function userLike()
{
if (Auth::check()) return $this->hasOne('App\Like')->where('user_id', Auth::user()->id);
return null;
}
But I get the error:
local.ERROR: exception
'Symfony\Component\Debug\Exception\FatalErrorException' with message
'Call to a member function addEagerConstraints() on null' in
/var/www/social/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php:680
As a side question, am I doing this right? Is this the correct way of doing this or is there a better way?
I'm not sure it is the right way to do this. In your model you should only declare your relationships:
public function userLike()
{
return $this->hasOne('App\Like');
}
And then in a controller or something you go get the like of your user like this:
class LikesController extends Controller {
public function getLike()
{
$like = null;
if (Auth::check()) {
$like = Like::where('user_id', Auth::user()->id)->first();
}
}
}
So we have a getLike() function that get the like of a user from your model Like where the user_id is equal to the authenticated user's id.
Hope it helps!
I'm not sure! But I think it is possible to use count! When it returns 0 you know that there are no records, so you can return null.
You can just use this style in your Like Model :
// return the number of likes
function userLikes()
{
$count = $this->where('user_id', $this->post_id)->count();
// check if not null
return $count ? $count : 0; // if null return 0
}

Call to undefined method Illuminate\Database\Query\Builder::intersect()

I want to make Laravel Authorization using gate..Where In user model
User.php
public function hasPermission($name)
{
$permission = Permission::where('name','=', $name)->first();
$permissions = \DB::table('role_permission')
->join('permissions', 'permissions.id', '=', 'role_permission.permission_id')
->select('role_permission.*')
->where('role_permission.permission_id', '=',$permission->id)
->get();
if(! $permissions) {
return false;
}
return !! $permission->intersect($this->$permission)->count();
}
In AuthserviceProvider
public function boot(GateContract $gate)
{
$this->registerPolicies($gate);
$gate->before(function($user, $ability) {
return $user->hasPermission($ability);
});
}
My Table structure like.
User has name,email,password,id
permission has name,id
role has name,id
role_permission has role_id,permission_id
can anyone help me to find out what's the error here?
intersect method belongs to Collection class. You can't use intersect method on Model. You may try by:
return !! collect([$permission])->intersect($this->$permission)->count();
$this->$permission should be an array or collection
I guess that's because you can apply intersect to a collection, while you're getting an error saying you that you're calling it over Illuminate\Database\Query\Builder.
I see you're calling it on $permission, that's currently a record (a model) of Permission. Probably that's just a typo, and you want to use $permissions instead of $permission.
Anyway, try to explain better what's the behaviour you're looking for, because it's not clear.

How to chain queries in laravel 5

I used to do something like this in code Igniter
$this->db->select('*');
$this->db->from($this::DB_TABLE);
if ($role == "manager") {
$this->db->where('is_manager',1);
}
if ($role == "staff") {
$this->db->where('is_staff',1);
}
$this->db->where('is_active', 1);
$this->db->order_by('last_name', 'asc');
$user_set = $this->db->get();
return $user_set;
How can I write a similar query like this in laravel 5. I new to laravel.
If you want to conditionally change the query parameters it's like:
$query = Model::select('*')
if ($role == "manager") {
$query = $query->where('is_manager',1);
}
if ($role == "staff") {
$query = $query->where('is_staff',1);
}
$user_set = $query->where('is_active', 1)->orderBy('last_name', 'asc')->get();
return $user_set;
But I think it would be more succinct like this (totally untested, but I think this would work):
return Model::select('*')
->where('is_manager', $role == 'manager' ? 1 : 0)
->where('is_staff', $role == 'staff' ? 1 : 0)
->where('is_active', 1)
->orderBy('last_name', 'ASC')
->get();
Yeah but we have this pretty great Eloquent ORM that didn't exist in Codeigniter.
Now it looks like:
Model::where('is_manager', 1)->where('is_active', 1)->orderBy('last_name', 'DESC')->get()
It's similar, but WAY more powerful.
Study the Eloquent docs and check out some of the basic examples in the Laracasts tutorials.

Laravel 4 - Eloquent 'where' only if exists

I'm working in a search engine, and I have something like this in my Controller:
$user = User::where('description', 'LIKE', '%'.$keyword.'%')
->where('position', $position)
->where('age', $age)
->orderBy('created_at', 'DES')
->paginate(10);
What I want is to use the $position and $age filters only if they exist. I mean, if I only set the keyword, I expect the application to show me all the users with this keyword (whatever its position and age are).
I know a way to do it... using if($position == '')... else..., but I would like to do (if possible) in my Eloquent consult. Something like... ->where('position' ? $position).
Any idea how to do it in the simplest way?
Thanks in advance!
Using if conditions would be the best way to do this. As far as I know the functionality your after isn't built into Eloquent.
I would do it using conditionals like so:
$query = User::where('description', 'LIKE', '%'.$keyword.'%');
if($position) {
$query->where('position', $position);
}
if($age) {
$query->where('age', $age);
}
$user = $query->orderBy('created_at', 'DES')->paginate(10);
If you want to keep your controller clean and avoid if - else you can create some scopes in your model.
For exemple :
public function scopePosition($query, $position)
{
//If $position in empty, return the query without where clause
return !($position == '') ? $query->where('position', $position) : $query;
}
And :
public function scopeAge($query, $age)
{
//If $age in empty, return the query without where clause
return !($age== '') ? $query->where('age', $age) : $query;
}
And then use it like this:
$user = User::where('description', 'LIKE', '%'.$keyword.'%')
->position($position)
->age($age)
->orderBy('created_at', 'DES')
->paginate(10);
More abour query scope:
http://laravel.com/docs/eloquent#query-scopes

Laravel query with hasmany relationship

I'm new to laravel so forgive me for the possible noobish question. Also, I did look into all the other 'similar' questions but either they're don't reproduce the right solution or i'm honestly having a hard time wrapping my head around it.
The scenario:
I have a Post model and a Subject model. This is what they look like at the moment.
in Post.php
public function subjects() {
return $this->belongsToMany('Subject', 'posts_subjects');
}
in Subject.php
public function posts() {
return $this->belongsToMany('Post', 'posts_subjects');
}
Now, what i need to achieve is:
In case an query parameter is passed to the request(ie q=Food) i want to return only the posts that contain the subject food in their subjects relationship and none of the others. if nothing is passed, then i just show everything...
This is what my PostsController's index action looks like atm.
public function index() {
$q = Input::get('q');
$posts = Post::all();
return View::make('posts.index', ['posts' => $posts]);
}
How would i go about doing that? would greatly appreciate some help.
Thanks a lot
PS. I'm able to get all the posts with this code.
This is untested code, but it probably will work for you, if you have only one Subject returned by that query:
public function index()
{
if($q = Input::get('q'))
{
if($subject = Subject::with('posts')->where('name', $q)->first())
{
$posts = $subject->posts;
}
else
{
$posts = array();
}
}
else
{
$posts = Post::all();
}
return View::make('posts.index', ['posts' => $posts]);
}

Resources