Problems with query function laravel - database

I would like to load the user, which has the appropriate url in the table invites stored. Unfortunately, I do not get the query written. How can I switch to the table "invites" and still load the right user to the page?
Relation:
One to one
Route
Route::get('/invite/{url}', 'Auth\RegisterController#show')->name('invite.show');
Table invites:
Schema::create('invites', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned()->nullable();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->text('greeting')->nullable();
$table->string('url')->unique();
$table->timestamps();
});
function
public function show($url)
{
$user = User::where(function ($query) use ($url) {
$query->where('invites.url', '=', $url);
})->first();
return view('invite_user', compact('user'));
}

Try this:
$user = User::whereHas('invites', function($query) use($url) {
$query->where('url', $url);
})->first();
Make sure that you have the invites relationship function in your User model like so:
public function invites() {
return $this->hasMany(Invite::class, 'user_id');
}

Related

How to get the name of role from pivot table for a users in laravel?

Admin.php [Middlewere]
public function handle($request, Closure $next)
{
if (Auth::check() && Auth::user()->role->name == 'admin') {
return $next($request);
}
return Redirect::route('home');
}
I want to check if the column name of roles table is equal to admin.
I have tried with Auth::user()->role->name == 'admin').
Error I am getting
Property [name] does not exist on this collection instance.
Reference Model
User.php [Model]
public function role()
{
return $this->belongsToMany(Role::class, 'role_user', 'user_id', 'role_id')->withTimestamps();
}
Reference table
users table
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->string('photo')->nullable();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->longText('cartitems')->nullable();
$table->longText('wishlist')->nullable();
$table->unsignedBigInteger('discount')->default(0);
$table->rememberToken();
$table->timestamps();
});
This is users table. Notice there is no role directly here.
roles table
Schema::create('roles', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('display_name');
$table->timestamps();
});
This is roles table. And every user have a role such as Superadmin, admin, seller orcustomer
role_user table
Schema::create('role_user', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->unsignedBigInteger('role_id');
$table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');
$table->timestamps();
});
In this pivot table make a relationship between users and roles table.
That's because you're trying to access a value on collection and your laravel relationship is BelongsToMany but rather HasOne/BelongsTo. You should rather pluck all the names and then check if it exist in_array
$roles = Auth::check() ? Auth::user()->role->pluck('name')->toArray() : [];
if (in_array('admin', $roles)) {
return $next($request);
}
I would recommend changing the role relationship to roles rather because a user can have many roles in this context.
you can use whereHas
if (Auth::check() && User::where('id',Auth::user()->id)->whereHas('role',function ($query){
$query->where('roles.name','=','admin');
})->first()!=null ) {
return $next($request);
}
It's because a user can have many roles as per your schema design.
User <=> Role : Many to Many Relation
So Auth::user()->role gives a collection of instances of Role Model. And you're trying to access name property on the collection which can't be done.
Change the if condition to this
if (Auth::check() && Auth::user->role()->where('name', 'admin')->exists()) {
I'd also suggest you to change the name of the relation from role to roles in your User Model. as roles is more informative about the type of relation user and role share.
public function roles(){
return $this->belongsToMany(App\Role::class, 'role_user' 'user_id', 'role_id');
}
Use whereHas
$role = User::where('id',Auth::user()->id)->whereHas('role',function ($query){
$query->where('name','=','admin');
})->first();
if (Auth::check() && isset($role) && !empty($role) ) {
return $next($request);
}

How to properly insert time when user leaves( user_left and user_joined got the same value)

In this code, I would like to get time when the user joined and left and store it to DB. What happens it that I get the same value in both 'joined' and 'left' tables. How to fix it so it would store different values?
Schema::create('user_info', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('ip');
$table->string('joined');
$table->string('left');
});
in LoginController
public function logout() {
$left = now();
auth()->logout();
session()->forget('name');
session()->put('left', $left);
return redirect('/');
}
in Model
protected $fillable = ['ip','name', 'joined'];
const CREATED_AT = 'joined';
const UPDATED_AT = 'left';
public static function storeUser() {
UserInfo::create([
'ip' => Request::ip(),
'name' => Auth::user()->name,
'joined' => now(),
]);
}
BroadcastServiceProvider.php
Broadcast::channel('chat', function ($user) {
$ip = Request::ip();
$time = now();
if (auth()->check() && !session()->has('name')) {
UserInfo::storeUser();
session()->put('name',$user->name);
return [
'id' => $user->id,
'ip' => $ip,
'name' => $user->name,
'joined' => $time,
];
}
});
This image illustates the behaviour after some changes you'll see below. It show that data with key 'left' for now goes not to the intended user but to the first user with this name.
The follow up of this question is here How to override this code so that it insert data properly?
CREATED_AT and UPDATED_AT are timestamps that gets changed by the Eloquent model, whenever a model gets created it's also modified or updated from a non-existing to existing so this is why you get the same value
In the logout function, update the user's left column
public function logout() {
$user_id = auth()->id(); // Get authenticated user ID
$user_info = App\UserInfo::find($user_id); // Get user info
$user_info->left = now(); // Change here
$user_info->save(); // Update here
auth()->logout();
session()->forget('name');
session()->put('left', $left);
return redirect('/');
}
According to your table, there's no way to distinguish between users and their info since the name is not unique
Make a user_id based relationship
User model
public function info()
{
return $this->hasOne(UserInfo::class);
}
UserInfo model
public function user()
{
return $this->belongsTo(User::class);
}
And in the user_infos migration
Schema::create('user_infos', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->string('name');
$table->string('ip');
$table->dateTime('joined');
$table->dateTime('left');
});
Cleaner Method
public function logout() {
$info = auth()->user()->info; // Get user info
$info->left = now(); // Change here
$info->save(); // Update here
auth()->logout();
session()->forget('name');
session()->put('left', $left);
return redirect('/');
}
Hope this helps

Getting value from another table through id

I am new to laravel. I have a table:
students_attendance.
In students_attendance I have a column named class_id, which refers to the students_classes table that also includes the class_id and class_name for each student.
In the frontend table I am getting the values from students_attendance table so the class_id is available, but what I need is the class_name.
How I can get the class_name?
//Migration for students_attendance
public function up()
{
Schema::create('students_attendances', function (Blueprint $table) {
$table->increments('id');
$table->integer('class_id')->index()->unsigned()->nullable();
$table->string('student_id');
$table->string('first_name');
$table->string('last_name');
$table->string('attendance');
$table->timestamps();
});
}
//Migration for students_classes
public function up()
{
Schema::create('students_classes', function (Blueprint $table) {
$table->increments('id');
$table->string('class_name');
$table->string('class_fee');
$table->string('class_teacher');
$table->timestamps();
});
}
//Students Class Model
class StudentsClass extends Model
{
protected $fillable = [
'class_name',
'class_fee',
'class_teacher'
];
public function students() {
return $this->hasMany('App\Students');
}
}
//Students Attendance Model
class StudentsAttendance extends Model
{
protected $fillable = [
'class_id',
'student_id',
'first_name',
'last_name',
'attendance'
];
public function studentsClass() {
return $this->belongsTo('App\StudentsClass');
}
}
From a StatusAttendance variable you can access the class name with $attendance->studentClass->class_name.
Assuming you have the class_id and you want to get the name of the associated class, you can simply do this:
$class = StudentsClass::find($class_id);
$class->class_name; // Outputs the name

User suggestions Laravel

I want to show user suggestions to the logged in user.
It should be displayed to users who the logged in user does not yet follow and which the user has not blocked and was blocked.
How can I query this accordingly?
Function:
$id = Auth::id();
$users = User::with('profile')->where('id', '!=', $id )->inRandomOrder()->get();
Relationship on Usermodel
public function followers()
{
return $this->belongsToMany(User::class, 'followers', 'leader_id', 'follower_id')->withTimestamps();
}
public function followings()
{
return $this->belongsToMany(User::class, 'followers', 'follower_id', 'leader_id')->withTimestamps();
}
public function blockers()
{
return $this->belongsToMany(User::class, 'blockers', 'leader_id', 'block_id')->withTimestamps();
}
public function blockings()
{
return $this->belongsToMany(User::class, 'blockers', 'block_id', 'leader_id')->withTimestamps();
}
Table Blockers
Schema::create('blockers', function (Blueprint $table) {
$table->increments('id');
$table->integer('block_id')->unsigned();
$table->integer('leader_id')->unsigned();
$table->timestamps();
$table->foreign('block_id')->references('id')->on('users')->onDelete('cascade');
$table->foreign('leader_id')->references('id')->on('users')->onDelete('cascade');
});
Table Follower
Schema::create('followers', function (Blueprint $table) {
$table->increments('id');
$table->integer('follower_id')->unsigned();
$table->integer('leader_id')->unsigned();
$table->timestamps();
$table->foreign('follower_id')->references('id')->on('users')->onDelete('cascade');
$table->foreign('leader_id')->references('id')->on('users')->onDelete('cascade');
You can use the whereDoesntHave() query method, which will check against the absense of a relation.
Firstly, you will need to get the currently authenticated user's id. Then which each check, you will need to pass this id to be used within the check.
Example:
$user_id = Auth::user()->id;
$suggestions = User::whereDoesntHave('followers', function ($query) use ($user_id) {
$query->where('follower_id', $user_id);
})
->whereDoesntHave('blockings', function ($query) use ($user_id) {
$query->where('block_id', $user_id);
})
->whereDoesntHave('blockers', function ($query) use ($user_id) {
$query->where('leader_id', $user_id);
})
->get();
as i found you have for relation in your UserModel follower, folloeing, blocker, blocking but you want to select users that dont have any relationship with this user, so use WhereDosentHave such as:
$users =User::where(id, $id)->WhereDoesntHave('followers')
->ORwhereDoesntHave('following')
->ORwhereDoesntHave('blocker')
->ORwhereDoesntHave('blocking')
->get();
i dont test it but i think that work just check name of relations

Cake PHP Translate Behavior, multiple field anomaly?

I use the core translator of CakePHP and i have an anomaly.
I have an application with 90 tables. 80 tables have at least on field to translate. Some tables have more than one field.
All tables have just few records (i'm in development step)
I have no problem in my application with all tables with only one field to translate but when i use tables with more than one field to translate, it seems that i have an infinite loop with at then end a problem of memory.
Exemple of a code
MarketsTable.php
class MarketsTable extends BaseTable {
public function initialize(array $config){
parent::initialize($config);
$this->setTable('markets');
$this->setDisplayField('id');
$this->setPrimaryKey('id');
$this->addBehavior('Translate', ['fields' => ['name_lang','description_lang']]);
}
public function buildRules(RulesChecker $rules) {
$rules->add($rules->isUnique(['name_lang']));
$rules->add($rules->existsIn(['language_id'], 'Languages'));
return $rules;
}
}
Market.php
class Market extends EntityBase{
use LazyLoadEntityTrait;
use TranslateTrait;
protected $_accessible = ['*' => true,'id' => false];
}
And finally i have a little thing very strange, but i imagine some specialist of PHP will explain me it. I found a "solution" to solve my problem.
If i a line of code in the class TranslateBehavior, the problem doesn't exist any more (the code start at the line 207 of TranslateBehavior.php)
public function beforeFind(Event $event, Query $query, $options){
$locale = $this->locale();
if ($locale === $this->getConfig('defaultLocale')) {
return;
}
$conditions = function ($field, $locale, $query, $select) {
return function ($q) use ($field, $locale, $query, $select) {
$q->where([$q->repository()->aliasField('locale') => $locale]);
if ($query->isAutoFieldsEnabled() || in_array($field, $select, true) || in_array($this->_table->aliasField($field), $select, true)) {
$q->select(['id', 'content']);
}
// line added by myself
$q->__toString();
return $q;
};
};
// ...
}
How this line "$q->__toString();"can solve my problem ???? :s

Resources