I have a table called lands which has the lands that belong to users, the user can occupy another user land and take it. So, I want to change the user_id in lands table to make it belong to the occupier.
Lands table:
$table->increments('id');
$table->string('name');
$table->smallInteger('size');
$table->smallInteger('type')->default(0)->comment('0 is village, 1 is city ');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users')
->onUpdate('cascade')->onDelete('cascade');
is there a method in eloquent to change the user_id to match new user ?
There are multiple ways via Eloquent to do this:
Making the user_id fillable:
if you make the user_id fillable within the Land model, you can fill it via a simple
$land->update(['user_id' => $newUser->id])
In your code.
Another choice is the recommended Eloquent way:
Use
$land->user()->dissociate();
$land->user()->associate($newUser->id);
$land->save();
To change the user currently stablished under the BelongsTo relationship.
Related
So in laravel I have a User table holding info such as id, home_address, email_address, phone_number, etc.
Users can participate in dinners (activity). If they don't show up to the dinners, admins should be able to ban the user from participating until they are manually unbanned.
The user table is "large enough" that it doesn't make sense to add new columns to the user table, but instead create a new table to keep the information seperate.
In my User migration file I have
Schema::create('dinner_ban', function (Blueprint $table) {
$table->unsignedBigInteger('id');
$table->foreign('id')->references('id')->on('users');
$table->dateTime('date_ban');
$table->dateTime('date_unban');
$table->string('reason')->nullable();
});
and in my User Model file I have
public function userBanned() {
return $this->belongsTo('App\Models\User', 'dinner_ban');
}
NOTE: dinner_ban does not have it's own individual Model Class.
The table is one way. When a user is banned, they are added to the dinner_ban table with today's date, an estimate future date where they would be unbanned (but of course can be before or after this date (in the future it would be automatic), and a reason for the ban (which doesn't need to be added/provided). When they are unbanned, they are removed from the table. No tracking is done as for how long or how many times someone has been banned. Its a simple check to see the user is banned or not. If they are banned, then they can not participate in dinners.
What I have above, is this a correct way of adding dinner_ban?
In the future there are 3 ways of using it.
If it's the admins, I want to return the whole DB and display the results on the page.
If it's the individual user, I want to check if their id exists in the ban database and return true (with when the ban started, when it ends, and the reason) or false.
And of course admins can edit the individual banned members and edit the reason/estimated unban list.
It is not a good idea to create a custom table like "dinner_ban" to store this kind of information.
It is better to create (if you don not already have) a "user_preferences" table with something like the following structure:
Schema::create('user_preferences', function (Blueprint $table) {
$table->unsignedBigInteger('id');
$table->foreign('user_id')->references('id')->on('users');
$table->json('value')->nullable();
});
and define the relation (and Cast) in "User" Model:
public function userPreferences() {
return $this->hasOne(UserPreferences::class);
}
Note: It's better to make "user_id" unique in preferences table and set "value" as json.
I installed auth in laravel 8 but I don't want to use the default table dedicated for authentication Users because I have my table Users_inf in this case I can't use migration, Users_inf also has 200 records.
Users_inf(user_id, password, user_name,privilege,active,CREATED_AT,UPDATED_AT).
CREATED_AT and UPDATED_AT added by me to be compatible with laravel.
I am using user_name for login not email. please, any suggestion for that issue.
The way I see it, you have two choices. Either alter the users table to have those fields, then import the data from one table to another - or, update your User model to use that table. In any case, you have to instruct Laravel to use the user_name field for authentication. Personally I would recommend going the first route, as that's the "Laravel way".
Approach 1: Altering the users table
Alter the migration of the users table, something along the lines of this. I would recommend you keep the ID field id rather than specifying your own user_id, as this is - again - the Laravey way of doing things.
Schema::create('users', function (Blueprint $table) {
$table->id('user_id'); // $table->id();
$table->string('user_name')->unique();
$table->string('privilege')->nullable();
$table->string('password');
$table->boolean("active")->default(true);
$table->rememberToken();
$table->timestamps();
});
Then to move the data over, run the following SQL query
INSERT INTO users (user_id, user_name, privilege, active, password, created_at, updated_at)
SELECT user_id, user_name, privilege, active, password, created_at, updated_at
FROM users_inf AS ui
WHERE NOT EXISTS(SELECT 1
FROM users AS u
WHERE u.user_name = ui.user_name)
Now you just need to instruct Laravel to use the user_name field, which we cover at the bottom of this answer.
Approach 2: Altering the User model
Laravel lets you specify which table and which field is the primary key, by adding simple properties to the model. Inside your User model class, add the following two lines,
protected $table = 'users_inf';
protected $primaryKey = 'user_id';
For both approaches: Using the user_name field as the login
Simply add the username() method to the User model class that returns the field which Laravel should use to lookup users in the given table.
public function username()
{
return 'user_name';
}
Laravel will give you so much "for free" and a lot of features will work more seamlessly when using the proper naming conventions. I suggest you follow the Laravel standards and naming conventions, as it will make it easier to work with the framework as a whole.
need some help about Laravel user auth. my knowledge about Laravel is very little, my experiences were deploying web app based on raw/pure PHP (never have experience with the framework).
The idea is to let an operator input the first and only one user to the system through the Laravel standard registration process, and this user will automatically become Super-User.
The super-user function is to manage normal-user registration (inside super-user session), by creating user & password and define the role of the normal-users.
I define the user's table like this, I add 'user_role' column to distinguished roles between users.
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->char('user_role')->nullable();
$table->rememberToken();
$table->timestamps();
});
'user_role' value for super-user must be 0, while another normal-users role should be numbers between 1-9.
content/views of each section of the webpage will be displayed depends on the 'user_role' value.
need help how to :
display user-registration page/url if none users defined in the user's table.
I need check 'user_role' every time I need to display a section of the page. how to achieve it?
From your table structure i assume you manage roles within users table. Now when you want to allow a specific role user for some part, just check the role of the user.
if(Auth::user()->user_role==0){
//do something its super user
}
In blade template you can check in the following way.
#if(Auth::user()->user_role==0)
<!--do some thing, its super user-->
#endif
To show registration form if there is no user in the table. In your blade you can select data from users table and then check if users table is empty.
<?php $users=App\User::all(); ?>
#if($users ===null)
<!--users table is empty show registration form-->
#endif
I want to create users which I can grant permissions.
I created a permissions model, which contains following attributes (id|name|displayName|desc)
1|xyz.edit|Edit xyz| Allow to edit xyz
2|xyz.create|Create xyz| Allow to create xyz
Thus I want to create relations like following:
public function getPermissions(){
return $this->hasMany('App\Permission');
}
But it does not work. Is there any way to create relations like
user has a lot of permissions but without creating same permissions for user?
I can make user model like id|pass|login|...|permissions
and in permissions storage permissions id splited with "," and in the getPermissions() function make something like this:
public function getPerms(){
foreach (explode($this->permssions,',')as $id ){
//here load from database perm by id add to array and return
}
}
Or a second option I see in this tutorial https://www.youtube.com/watch?v=Kas2w2DBuFg is to make another table like user_perms with fields
id|user_id|perms|id
but what option is the best to do this?
Can you post the code in both your models? (the user model and permission model?) without seeing that, I can't see what type of relationship you're using, although it looks like you're using a one-to-many.
Either way...
The way you can have users an assign them permissions, without worrying about groups is by using a many-to-many relationship. This requires 3 tables. The user table, the permission table, and a pivot table.
You can read about many-to-many relationships here: https://laravel.com/docs/5.5/eloquent-relationships#many-to-many
But to give you a rundown...
User model
public function permissions(){
return $this->belongsToMany('App\Permission');
}
Permission model
public function users(){
return $this->belongsToMany('App\User');
}
create_users_table migration (field names don't really matter, just make sure you have the increments() one)
$table->increments('id');
$table->string('name');
(etc, standard migration stuff)
create_permissions_table migration (field names don't really matter, just make sure you have the increments() one)
$table->increments('id');
$table->string('name');
$table->string('long_name');
(etc, standard migration stuff)
and for the pivot table, you need to use the singular name of the two tables in alphabetical order (or at least, thats the default)
create_permission_user_table (these two field names are important, laravel expects these names, you don't need any other fields... you can also setup foreign key relationships if you want to be thorough)
$table->integer('permission_id');
$table->integer('user_id');
and then to give a user a permission, you would just do
// Grab your user and permission, however you do that...
$permission = \App\Permission::first();
$user = \App\User::first();
// Then save the permission to the user (or the other way around, but it makes more sense this way)
$user->permissions()->save($permission);
And that will let you have users with permissions :)
then you can access an array of permissions with $user->permissions and do whatever logic checks you need to check if they are allowed to do things!
I have a question that I'm not sure how to solve or even phrase for finding an answer.
I have a Company Model & User Model that are related Many-to-Many.
I want to have a user_pins table. A user can belong to multiple companies and therefore have a different pin within each company. The pin is unique within a company, no two users within a company can have the same one. Users in different companies can have the same one.
So for the company it is One to Many, for the user it is One to Many, but altogether it is many to many, Im not sure if that makes sense.
I have the table set up as
Schema::create('user_pins', function (Blueprint $table) {
$table->integer('user_id')->unsigned();
$table->integer('company_id')->unsigned();
$table->string('pin');
$table->foreign('user_id')->references('id')->on('users')->onUpdate('cascade')->onDelete('cascade');
$table->foreign('company_id')->references('id')->on('companies')->onUpdate('cascade')->onDelete('cascade');
$table->primary(['user_id', 'company_id', 'pin']);
});
How do I relate this table in the models and use Eloquent to access/create/update it so it stores both the user and company?
Firstly, I would change the name to company_user so that it follows the same naming convention that Laravel would use out of the box. (you wouldn't have to do this as you can specify the pivot table name in the relationship but if there isn't a reason to stick with user_pin it makes sence to follow convention :) )
Then I would remove the primary key from being a compound of all 3 fields and just have it on the company_id and user_id.
Lastly, as a PIN only has to be unique for a company, I would just put the unique index on those two columns e.g.
Schema::create('company_user', function (Blueprint $table) {
$table->integer('company_id')->unsigned()->index();
$table->integer('user_id')->unsigned()->index();
$table->string('pin');
$table->foreign('user_id')->references('id')->on('users')->onUpdate('cascade')->onDelete('cascade');
$table->foreign('company_id')->references('id')->on('companies')->onUpdate('cascade')->onDelete('cascade');
$table->primary(['company_id', 'user_id']);
$table->unique(['company_id', 'pin']);
});
Then for the relationship in the model I would have something like:
return $this->belongsToMany('App\Company')->withPivot('pin');
and
return $this->belongsToMany('App\User')->withPivot('pin');
Examples of use with pivot
All user pins for a company:
$company->users->lists('pivot.pin');
Users pin for a specific company
$user->companies()->where('id', $id)->get()->pivot->pin;
Users pin for the first company relationship:
$user->companies->first()->pivot->pin;
Hope this helps!