Null value on updating column value during migration - laravel

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()]);
}

Related

Laravel Migration default unique value

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

post view counter function returns user_id error laravel

I'm trying to implement some basic viewcounter to my laravel project. For some reason it returns an odd error:General error: 1364 Field 'user_id' doesn't have a default value. No when I remove the function from the model. The show page works, so I don't see why it is telling me user_id doesn't have a default value, neither why this functions won't work properly
the table:
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id');
$table->string('title');
$table->string('slug')->unique();
$table->text('body');
$table->string('image');
$table->string('category');
$table->boolean('active')->default(1);
$table->bigInteger('reads')->unsigned()->default(0)->index();
$table->timestamps();
});
}
the function in the post model:
public function incrementReadCount() {
$this->increment('reads');
return $this->save();
}
The function before returnin the show view:
public function mount($slug)
{
$this->post = Post::where('slug', $slug)->first();
}
public function render(Post $post)
{
$post->incrementReadCount();
return view('livewire.post-show')->layout('layouts.guest');
}
}
Since you are calling the save method after incrementing, Laravel will try to create a new post record, but without providing a user_id. (hence the "Field 'user_id' doesn't have a default value" error). You don't want to create a new record.
Just remove the save() call from the incrementReadCount method:
public function incrementReadCount()
{
$this->increment('reads');
}

How to get just one user data in Laravel with eloquent?

I use Laravel 8. I want to get the user proccess course, but I get all users proccess.
In User.php
public function courses()
{
return $this->belongsToMany(Course::class);
}
Course.php
public function progresses()
{
return $this->hasMany(Progress::class);
}
Progress.php is empty.
Course table
Schema::create('courses', function (Blueprint $table) {
$table->id();
$table->string('title');
...
$table->timestamps();
});
Progress table
Schema::create('progress', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->onDelete('cascade');
$table->foreignId('course_id')->constrained()->onDelete('cascade');
$table->integer('percent');
$table->timestamps();
});
CourseController
public function index()
{
$userCourses = User::where('id', 1)->with('courses.progresses')->first();
return $userCourses;
}
And this return:
But I only wanted proccess where user_id = 1.
With() method can constrain eager loads with a specific array annotation. This is also described in the documentation.
$userId = 1;
$userCourses = User::where('id', $userId)
->with(
[
'courses.progresses' => function ($query) use ($userId) {
$query->where('user_id', $userId)
},
]
)->first();

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`)");

Laravel 4 Pivot Table (many to many) not loading

I have 2 tables: 'users' and 'nests' and 1 pivot table: 'nest_user'. In my pivot table I have email addresses I want to filter against so I can grab all the nests which have the associated email addreses. Here is my scehma:
public function up()
{
Schema::create('users', function(Blueprint $table)
{
$table->increments('id');
$table->string('username');
$table->text('bio');
$table->string('picture');
$table->string('email');
$table->string('password');
$table->integer('visits');
$table->integer('nest_id');
$table->timestamps();
});
}
public function up()
{
Schema::create('nests', function(Blueprint $table)
{
$table->increments('id');
$table->string('name');
$table->string('info');
$table->integer('note_id');
$table->integer('website_id');
$table->integer('image_id');
$table->integer('video_id');
$table->integer('location_id');
$table->integer('user_id');
$table->integer('share_id');
$table->string('inviteAuth');
$table->string('tid');
$table->timestamps();
});
}
public function up()
{
Schema::create('nest_user', function(Blueprint $table)
{
$table->increments('id');
$table->integer('user_id');
$table->integer('nest_id');
$table->string('inviteEmail');
$table->timestamps();
});
}
I can do this no problem based on the User ID like this:
Route::get('/t1', function () {
$nest = User::find(2)->nest()->where('inviteEmail', '=', 'martinelli#gmail.com')->get();
foreach( $nest as $nest)
echo $nest->name, ': ', $nest->pivot->inviteEmail, "</br>";
});
I can get the nest and name and the email in the pivot - awesome...However, I want to find ALL the 'nests' which have the associated email which is NOT tied to a user ID. This is getting me closer but it is still not working:
Route::get('/t4', function () {
$users = User::all();
foreach($users as $users)
{
$nests = $users->with(array('nest' => function($query) {
$query->where('inviteEmail', '=', 'martinelli#gmail.com');
}))->get();
foreach($nests->nest as $nest)
{
echo $nest->name,"<br />";
}
}
});
I am getting this error:
Undefined property: Illuminate\Database\Eloquent\Collection::$nest
I'm not sure I fully understand your question, but your last code block doesn't make sense. You'll want to do the with while fetching the users. Also, the error you're getting makes sense, because the $nests (Collection) doesn't have a $nest property.
Again, I'm not sure this is what you're after, but give this a try:
Route::get('/t4', function () {
// Get all users and their nests where nests are filtered by inviteEmail
$users = User::with(array('nest' => function($query) {
$query->where('inviteEmail', '=', 'martinelli#gmail.com');
}))->get();
// Loop through all users
foreach($users as $user)
{
// I'm asuming you defined the relation as nests() in your User model.
foreach($user->nests as $nest)
{
echo $nest->name . "<br />";
}
}
});

Resources