Laravel Model without a Database? - php

I'm developing a system in which i have different roles for accesing. The role is present in the Users table as an integer value.
I've created a model called roles and in this model i dont need a database connection or a table. I did set some constant values representing roles matching the role field in the user table.
So what's the problem ? It seems that i can't have relations with the roles model if this hasn't a table associated in the database.
This is my roles model:
class Roles extends Model {
const ROL_ADMINISTRADOR = 1;
const ROL_DIRECTOR = 2;
const ROL_PROFESOR = 3;
const ROL_RECOPILADOR = 4;
private $rol_id;
private $roles = [
self::ROL_ADMINISTRADOR => 'Administrador',
self::ROL_DIRECTOR => 'Director',
self::ROL_PROFESOR => 'Profesor',
self::ROL_RECOPILADOR => 'Recopilador'
];
/**
* RELACIONES
*/
public function _usuarios() {
return $this->hasMany(Usuarios::class, "rol", "rol_id");
}
/**
* FORMATEADORES
*/
/**
* FUNCIONES
*/
public function nombre() {
return $this->roles[$this->rol_id];
}
}
This is my users model
class Usuarios extends Authenticatable {
use Notifiable;
const STATUS_ACTIVO = 1;
const STATUS_INACTIVO = 0;
protected $table = 'usuarios';
protected $primaryKey = 'usuario_id';
/*
* RELACIONES
*/
public function _rol() {
return $this->hasOne(Roles::class, 'rol', 'rol_id');
}
public function _perfil() {
return $this->hasOne(Perfiles::class, "usuario", "usuario_id");
}
/*
* FORMATEADORES
*/
}
But i got this error
Base table or view not found: 1146
When i try to do this
<?= Auth::user()->_rol->nombre() ?>
=========================================================================
I think i've found the solution.
I did the following changes:
1.- in the roles model I did add the constructor method and customized it
public function __construct($rol) {
parent::__construct();
$this->rol_id = $rol;
}
2.- In the users model change the method to this
public function _rol() {
return new Roles($this->usuario_id);
}
There is a thing here: if the method is called like this '_rol' the model will think is about a relation and will required a relation response so is neccesary to call it this way '_rol()' (with the parenthesis)
<?= Auth::user()->_rol()->nombre() ?>

You only need the Role model if you have another table to store the roles.
If you, instead, have the role represented as a field in the users table, you can access it just doing:
$role = $user->role;

I suggest you to use https://github.com/artesaos/defender to manage roles and permitions.

Related

Sort belongsToMany relation base on field in belongTo relation Laravel Eloquent

I have a scenario where User has a belongsToMany relation with PortalBreakdown, PortalBreakdown has a belongsTo relation with Portal. Portal has order column in it. I have a method listing_quota($id) in UserController which returns all breakdowns of the user. I want to sort these breakdowns based on order column of the portal. Below are the code of classes and a method I have tried.
class User extends Model {
protected $table = 'user';
public function listing_quota() {
return $this->belongsToMany('App\PortalBreakdown', 'user_listing_quota')->withPivot(['quota']);
}
}
class PortalBreakdown extends Model {
protected $table = 'portal_breakdown';
public function portal() {
return $this->belongsTo('App\Portal');
}
}
class Portal extends Model {
protected $table = "portal";
protected $fillable = ['name', 'description', 'order'];
}
Below is the method where I am trying to return sorted by order. I tried few things some of which can be seen in commented code but not working.
class UserController extends Controller {
public function listing_quota($id)
{
$user = User::with(['listing_quota' => function ($query) use ($id) {
// $query->sortBy(function ($query) {
// return $query->portal->order;
// });
}, 'listing_quota.portal:id,name,order'])->findOrFail($id);
// $user = User::with(['listing_quota.portal' => function ($q) {
// $q->select(['id', 'name',order']);
// $q->orderBy('order');
// }])->findOrFail($id);
return $this->success($user->listing_quota);
}
}
I also tried chaining orderBy directly after relation in Model class but that's also not working from me. Thank you in advance.
NOTE: I am using Laravel Framework Lumen (5.7.8) (Laravel Components 5.7.*)

How To Get Article's Users and Comments With Eloquent

There are three database tables users, articles and a joining table article_users_comments, which holds the comment, the user id commented the article and the commented article id.
I can achieve the following thing with pure SQL join, but I want to do it with Eloquent, I thought that it would be quite easy, but I am kind of confused right now.
I have been trying different things, but it still doesn't work.
// User
class User extends Authenticatable implements MustVerifyEmail,CanResetPassword{
public function comments()
{
return $this->hasMany('App\ArticleComments');
}
}
// Article
class Article extends Model{
public function getArticles(){
$articles = Article::paginate(3);
return $articles;
}
public function getSingleArticle($title){
$article = Article::where('title','=',$title)->get();
return $article;
}
public function articleComments()
{
return $this->hasMany('App\ArticleComments');
}
}
// ArticleComments
class ArticleComments extends Model{
protected $table = 'article_users_comments';
public $timestamps = false;
public function article()
{
return $this->belongsTo('App\Article');
}
public function user()
{
$this->belongsTo('App\User');
}
}
// ArticleController(showing only the show method), which passes the data to the certain view
instantiating the Article Model
class ArticleController extends Controller{
/**
* Display the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function show($title)
{
$removeDashesFromUrl = str_replace('-',' ',$title);
$am = new Article();
$data = $am->getSingleArticle($removeDashesFromUrl);
return view('article',['article'=>$data]);
}
}
I want to get the comments and the users(which have commented the article) for a certain certain article.
You should set the foreign key in your articleComments and article relations:
Eloquent determines the default foreign key name by examining the name of the relationship method and suffixing the method name with _id. However, you may pass a custom key name as the second argument to the belongsTo method:
Article Model
public function articleComments()
{
return $this->hasMany('App\ArticleComments','commented_article_id');
}
ArticleComments Model
public function article()
{
return $this->belongsTo('App\Article','commented_article_id');
}
You can get the comments from a article using the relation:
$article = Article::find($id);
$article->articleComments; // This will return all comments for the given article
You could use a foreach loop and access each attribute from each comment:
foreach($article->articleComments as $comment)
{
echo $comment->id;
echo $comment->user->id;
echo $comment->user->username;
.
.
.
}
You can access the user and any of his attributes just calling the relation in your comment like i did above.
For more info: click here.
Note: i strongly recommend you changing your model name to Comment, we don't use model names in the plural, always in singular.

Laravel 5.3: Can not access anymore the admin dashboard

anyone can help me here with a problem?
I'm creating one area in Laravel where Users can login accordingly to their role.
Used an artisan command to create the auth, quite straightforward so far.
Then, I started by changing the table name and the primary key of the table 'users' in the DB.
With this done, one needs to update the User Model (automatically generated by the artisan command) and let the model know where exactly is the table 'users' and which one is the primary key for that table.
protected $table = 'users';
protected $primaryKey = 'userID';
After this, once I go to the browser and do a normal login, it doesn't let me access the admin dashboard and I'm getting prompt with trying to get a property of a non-object.
This comes from the fact that once the table and the primary key are changed like I've done before, '$this' is not in object context anymore.
How can I make it work?
User.php:
class User extends Authenticatable
{
(...) public function isAdmin(){
if($this->roles->Role_Type == "Admin" && $this->is_active == 1){ //this one is the line 83 where the error is
return true;
}
return false;
}
(...)
}
You have error in this code
$this->roles->Role_Type
"$this->roles" returns the roles corresponding to that user and then you taken the field "Role_Type".
In your scenerio, there is no roles attached to that user.
So this "$this->roles" returns null.
So you could not take the value "Role_Type". This causes error.
You have to do the following
if($this->roles != null && $this->roles->Role_Type && $this->is_active == 1) {
return true;
} else {
return false;
}
Note: your code will work with has one relationship.
Class User extends Model
{
public function roles()
{
return $this->hasOne('App\Role');
}
}
If you want to use roles and permission in effecient manner, try this package https://github.com/romanbican/roles
It worked this way:
went to the DB and deleted the strong relationships (FKs) stablished between the tables, they're always a pain for Developers, requiring much more code just to have them there.
Thanks to you all for all the help and bellow is the code that used and worked fine:
<?php
namespace App;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
/**
* The attributes that are mass assignable.
*
* #var array
*/
//
protected $table = 'users';
protected $primaryKey = 'userID';
protected $fillable = [
'name',
'email',
'password',
'roleID',
'photoID',
'is_active'
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function role(){
return $this->belongsTo('App\Role', 'roleID');
}
public function photo(){
return $this->belongsTo('App\Photo', 'photoID');
}
// public function setPasswordAttribute($password){
//
//
// if(!empty($password)){
//
//
// $this->attributes['password'] = bcrypt($password);
//
//
// }
//
//
// $this->attributes['password'] = $password;
//
//
//
//
// }
public function isAdmin(){
if($this->role->Role_Type == "Admin" && $this->is_active == 1){
return true;
}
return false;
}
public function posts(){
return $this->hasMany('App\Post');
}
public function getGravatarAttribute(){
$hash = md5(strtolower(trim($this->attributes['email']))) . "?d=mm&s=";
return "http://www.gravatar.com/avatar/$hash";
}
}

Laravel eager load a relationship based on the result of relationship method

I have the following entities:
User
class User extends Eloquent implements UserInterface, RemindableInterface {
use UserTrait, RemindableTrait;
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'members';
protected $primaryKey = 'member_id';
public function licences(){
return $this->hasMany('Licence', 'subid', 'member_id');
}
}
Licence
class Licence extends \Eloquent {
protected $table = 'licence';
protected $primaryKey = 'id';
protected $active = false;
const DATE_FORMAT = 'Y-m-d';
protected $fillable = [];
public function __construct(){
$this->checkifIsActive();
}
public function owner(){
return $this->belongsTo('User', 'member_id', 'subid');
}
public function checkifIsActive(){
if($this->start_date <= date($this->DATE_FORMAT) && $this->end_date >= date($this->DATE_FORMAT)) $this->active = true;
}
}
One user can have many licences, and the licenses that the user has may be either active or inactive - this is determined by a start and end date on the licence.
I'm trying to load a User object, and at the same time pull in their licences, but only those that are active.
Within the licence model, I am setting the 'active' variable to true, when the object is instantiated, so we have a way of knowing the status of the licence.
The code so far that I've tried is:
return User::findOrFail($id)->with('licence.active')->get();
However, this is not quite right - as there's no actual condition check done on the 'licence.active'.
How would I return a user, loaded by an ID, along with the licences they have associated that are have a boolean 'active' variable set to 'true'?
You can use eager loading constraints to query the relation like so;
$user = User::with(array('license' => function($query){
$query->where('start', '<=', Carbon::now())
$query->where('end', '>=', Carbon::now())
}))->find($id);
This will then only return the licenses that are active.
Optionally you could query the result of the relationship like so;
public function activeLicences(){
return $this->hasMany('Licence', 'subid', 'member_id')->where('start', '<=', Carbon::now())->where('end', '>=', Carbon::now());
}
Then all you would have to do is the following to get the results;
$user = User::with('activeLicenses')->find($id)
Please Note: This has not been tested.

Getting related user attributes in Phalcon

I'm new to Phalcon, just trying to write my first application, and facing an issue that the documentation isn't very clear on, which is in regards to getting related information.
At the moment I have 1 controller, the User controller.
<?php
class UserController extends Phalcon\Mvc\Controller
{
public function homeAction()
{
$users = Users::query()
->where('id = :id:')
->bind(array('id' => '1'))
->execute();
$user = $users->getFirst();
$this->view->setVar('user', $users->getFirst());
$primaryStatus = Status::query()
->where('userId = :id:')
->bind(array('id' => '1'))
->execute();
$this->view->setVar('primaryStatus', $primaryStatus->getFirst());
$status = Status::query()
->where('userId != :id:')
->bind(array('id' => '1'))
->execute();
$this->view->setVar('status', $status);
}
}
And I have some models setup, Users, Attributes and UsersAttributes
and my view setup in volt.
This is my Attributes model
<?php
class Attributes extends Phalcon\Mvc\Model
{
public $id;
public $name;
public function initialize()
{
$this->hasMany('id', 'UsersAttributes', 'attributesId');
}
}
My Users model
<?php
/**
* Users class
*
* Represents Holla users
*
*/
class Users extends Phalcon\Mvc\Model
{
public $id;
public $name;
public $username;
public $password;
public $email;
public $active;
public $createdDate;
public function getSource()
{
return 'users';
}
public function initialize()
{
$this->hasMany('id', 'UsersAttributes', 'userId');
$this->hasManyToMany(
'id',
'UsersAttributes',
'userId', 'attributeId',
'Attributes',
'id'
);
}
}
and my UsersAttributes model
<?php
/**
* Users attributes class
*
* Represents Holla users attributes
*
* #Source('usersAttributes');
*
*/
class UsersAttributes extends Phalcon\Mvc\Model
{
public $id;
public $userId;
public $attributeId;
public $attributeValue;
public function getSource()
{
return 'usersAttributes';
}
public function initialize()
{
$this->belongsTo('userId', 'Users', 'id');
$this->belongsTo('attributeId', 'Attributes', 'id');
}
}
I have 3 tables
users
id e.g. 1
name e.g. andre
username e.g. andrefigueira
attributes
id e.g. 1
attributeName e.g. profileImage
attributeDefaultValue e.g. placeholder.jpg
usersAttributes
id e.g. 1
userId e.g. 1
attributeId e.g. 1
attributeValue e.g. andre.jpg
In my controller I am doing a query and assigning the first result to a view property which is the user property, but I cannot figure out how to access specific user attributes from the get related method implementation.
I'd like to be able to in my volt do something like:
The name of the attributes is defined in the attributes table, then assigned a value and user in the usersAttributes table.
{{ user.userAttributes.profileImage }}
How would I go about accomplishing this? I have searched through a lot of different posts and the documentation with little luck...
Thanks in advance
One to many relation returns the container of zero or more records:
{% for r in user.userAttributes %}
{{ r.profileImage }}
{% endfor %}
I've realised my error, everything was working as it should, Phalcon simply won't map my structure database in this way as I define an attribute name in the attributes table, but the user defined value in the usersAttributes table. Hence no way to map it by the standard way so I had to create a new method and instantiate it elsewhere to pass the parameters to my view.
The code I've used to solve the problem is in the Users model and simply appends the attributes as an object to the user result object.
public static function fetchUserAttributes($userId)
{
$modelsManager = Phalcon\DI::getDefault()->getModelsManager();
$phql = '
SELECT name, attributeValue
FROM Attributes
LEFT JOIN UsersAttributes
ON UsersAttributes.userId = :userId:
AND Attributes.id = UsersAttributes.attributeId
';
$rows = $modelsManager->executeQuery($phql, array('userId' => $userId));
$attributesObj = new \stdClass();
foreach($rows as $row)
{
$attributesObj->{$row['name']} = $row['attributeValue'];
}
return $attributesObj;
}
public function afterFetch()
{
//Attach user attributes
$this->attributes = Users::fetchUserAttributes($this->id);
}

Categories