Laravel Migration default unique value - laravel

I have a migration which creates users, now I would like to add that migration and give each new user a unique random value from my array. So far the values are random but not unique, how can I do that?
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->string('theme_color')->default($this->generateColor())
->after('password')
->unique();
});
}
public function down()
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('theme_color');
});
}
public function generateColor()
{
$colors = [
'#94A3B8',
'#64748B',
'#F87171',
'#EA580C',
'#FDE68A',
'#713F12',
'#A3E635',
'#4ADE80',
'#A7F3D0',
'#99F6E4',
'#22D3EE',
'#0284C7',
'#2563EB',
'#8B5CF6',
'#D946EF',
'#9D174D',
'#F43F5E'
];
$k = array_rand($colors);
return $colors[$k];
}

Migration runs only once. So, you cannot set different values there, What your migration will do is it will set one random value as default forever.
To achieve this use Eloquent: Mutators & Casting (setter method) in the Laravel model, check the documentation https://laravel.com/docs/8.x/eloquent-mutators#defining-a-mutator

Related

accessing nested relationship in laravel 5

i have 3 models like below :
Date
Property
PropertyDetail
and here is my migration for tables i write in order
Date :
public function up()
{
Schema::create('dates', function (Blueprint $table) {
$table->bigIncrements('id');
$table->dateTime('date');
$table->timestamps();
});
}
Property :
public function up()
{
Schema::create('properties', function (Blueprint $table) {
$table->bigIncrements('id');
$table->integer('type');
$table->text('title');
$table->integer('base_capacity');
$table->timestamps();
});
and PropertyDetail :
public function up()
{
Schema::create('property_details', function (Blueprint $table) {
$table->bigIncrements('id');
$table->integer('property_id');
$table->string('state');
$table->string('city');
$table->timestamps();
});
}
i tried to remove unnecessarily fields from migration so to keep it clean so here is my 2 relations bettwen date and proeprties
Datemodel :
public function properties() {
return $this->belongsToMany(Property::class);
}
and propery model :
public function dates(){
return $this->belongsToMany(Date::class);
}
public function features(){
return $this->hasMany(Feature::class);
}
ok now finally in my controller i want to do this :
$search = Date::with('properties')
->where('date',$someday)->get()
->and some how here i want to select the city from the property detail table
;
so here is my problem , now i can easily access properties and show thier name but from this relation how can i access features relation and select the city from there should i use joins or some thing there i hope i was clear enough that what i want to do
You can do this:
Property model:
public function details(){
return $this->belongsToMany(Details::class,'property_details','id','property_id');
}
and in Date model:
public function properties() {
return $this->belongsToMany(Property::class);
}
public function propertiesDetails() {
return $this->properties()->with('details');
}
and in your controller you can get detail of properties by use:
$search = Date::with('propertiesDetails')
->where('date',$someday)->get();
now you can access to details of properties.
Hope it helps.

Laravel 5.4 belongsToMany relationship returns empty

In Laravel 5.4 I'am trying to set up a Many To Many Relation. but the belongsToMany returns empty! Here's my migrations and models.
botusers Table:
public function up()
{
Schema::create('botusers', function (Blueprint $table) {
$table->increments('id');
$table->integer('t_id');
$table->string('first_name');
$table->string('last_name');
$table->string('username');
$table->string('mobile');
$table->timestamps();
});
}
candidates Table:
public function up()
{
Schema::create('candidates', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('token');
$table->string('degree');
$table->integer('age');
$table->text('desc');
$table->string('photo_url');
$table->string('cv_url');
$table->timestamps();
});
}
Third table, botuser_candidate Table:
public function up()
{
Schema::create('botuser_candidate', function (Blueprint $table) {
$table->integer('botuser_id');
$table->integer('candidate_id');
});
}
and the votes() method in Botuser Model:
public function votes()
{
return $this->belongsToMany(Candidate::class)->get();
}
When I fire the votes() method returns an empty array. and I also tested bellow method too,
public function votes()
{
return $this->belongsToMany(Candidate::class,'botuser_candidate','botuser_id','candidate_id')->get();
}
What I missed here? What should I do?
Edit:
I also added the foreign keys to the relation but the result is still same!
I would suggest you remove the get() method on the belongsToMany
Then query the database with
$c=new App\Candidate;
$c->with('votes')->get()
if you still want to use $c->votes() then you would have to do some changes to your functions. Lets use scope to achieve it.
public function candidates()
{
return $this->belongsToMany(Candidate::class,'botuser_candidate','botuser_id','candidate_id');
}
public function scopeVotes($query)
{
return $query->with("candidates")->get();
}
Then now we can call $v->votes() and it should return all your record.
Calling get() directly on belongsToMany method will return empty array.

Null value on updating column value during migration

I'm trying to add a new column slug to an existing table devices and assign random unique values to it.
The following is my migration script.
public function up()
{
Schema::table('devices', function(Blueprint $table){
$table->string('slug');
});
$ids = DB::table('devices')->where('slug','')->pluck('id');
//dd($ids);
foreach ($ids as $id)
{
Device::whereId($id[0])->update(array('slug' => uniqid()));
}
}
The migration is running perfectly. But the slug field is an empty string after the migration. But it should be a unique string.
What might be the problem?
I think that problem with loop, try this:
foreach ($ids as $id)
{
Device::whereId($id)->update(array('slug' => uniqid()));
}
Also, you can make simpler
public function up()
{
Schema::table('devices', function(Blueprint $table){
$table->string('slug');
});
Device::update(['slug' => uniqid()]);
}

How to delete Unique key on multiple columns?

How do I reverse a unique key added on multiple columns in Laravel? Basically, what should go in the down() function of this migration code:
public function up()
{
Schema::table('topics', function($table)
{
$table->unique(array('subject_id', 'grade_id', 'semester_id', 'name'));
}
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('topics', function($table)
{
}
}
To drop a unique index, you use dropUnique('name_of_index').
If you're not specifying an index name in the second parameter of unique(), the name of the index will be tableName_fieldsSeperatedByUnderscore_unique.
public function down()
{
Schema::table('topics', function($table)
{
$table->dropUnique('topics_subject_id_grade_id_semester_id_name_unique');
}
}
There are two approaches to drop unique index :
First Approach :
In dropUnique() function we can pass array so that you don't need to use exact unique index name like "tableName_fieldsSeperatedByUnderscore_unique". Here is code snippet
Schema::table('users', function (Blueprint $table) {
$table->dropUnique(['email']);
});
This will drop the unique index of column 'email'.
Second Approach:
This approach is exactly same as described by Marwelln,still I would like to put it here again. You can pass unique index name in the dropUnique(), it will also work. But be sure that you are confident about unique index name.Code for that looks like this:
Schema::table('users', function (Blueprint $table) {
$table->dropUnique('users_email_unique');
});

schema builder laravel migrations unique on two columns

How can I set a unique constraints on two columns?
class MyModel extends Migration {
public function up()
{
Schema::create('storage_trackers', function(Blueprint $table) {
$table->increments('id');
$table->string('mytext');
$table->unsignedInteger('user_id');
$table->engine = 'InnoDB';
$table->unique('mytext', 'user_id');
});
}
}
MyMode::create(array('mytext' => 'test', 'user_id' => 1);
// this fails??
MyMode::create(array('mytext' => 'test', 'user_id' => 2);
The second param is to manually set the name of the unique index. Use an array as the first param to create a unique key across multiple columns.
$table->unique(array('mytext', 'user_id'));
or (a little neater)
$table->unique(['mytext', 'user_id']);
Simply you can use
$table->primary(['first', 'second']);
Reference: http://laravel.com/docs/master/migrations#creating-indexes
As an example:
Schema::create('posts_tags', function (Blueprint $table) {
$table->integer('post_id')->unsigned();
$table->integer('tag_id')->unsigned();
$table->foreign('post_id')->references('id')->on('posts');
$table->foreign('tag_id')->references('id')->on('tags');
$table->primary(['post_id', 'tag_id']);
});
If you have a default unique index with one column and you will change it with two columns, or create a new one with two columns, this script will do that for you:
public function up()
{
Schema::table('user_plans', function (Blueprint $table) {
$table->unique(["email", "plan_id"], 'user_plan_unique');
});
}
public function down()
{
Schema::table('user_plans', function (Blueprint $table) {
$table->dropUnique('user_plan_unique');
});
}
DB::statement("ALTER TABLE `project_majr_actvities`
ADD UNIQUE `unique_index`(`activity_sr_no`, `project_id`)");

Resources