Yii2 migration - add column after other one - yii2

I want to add a new column through migration in Yii2, using this code:
public function up()
{
$this->addColumn('news', 'priority', $this->integer());
}
public function down()
{
$this->dropColumn('news', 'priority');
}
And it works but I want it to be second column, after name.
It is possible?

OK, can you try this:
$this->addColumn('news', 'priority', 'integer AFTER `name`');

Since v2.0.8 you can also do the following:
$this->addColumn('news', 'priority', $this->integer()->after('name'));
See https://github.com/yiisoft/yii2/blob/2.0.8/framework/db/ColumnSchemaBuilder.php#L209

Related

Method Illuminate\Database\Eloquent\Collection::detach does not exist. (how can I solve?)

I need to delete and detach all relationship between BrandName table and stellar_category table.
public function destroy($id)
{
$brand_name = BrandName::find($id);
$brand_name->stellar_category->detach();
$brand_name->delete();
return back()->withMessage('Your Brand is Deleted');`enter code here`
}
Try to change it to
$brand_name->stellar_category()->detach();

Insert new column from existed column in Laravel

I had data in my database. Now i want to add a column
$table->string('md5_url');
It work. But now i want to add unique index on md5_url. But it don't work because rows in my database have same value(=default value).
So what should i do if i want to create new column form existed column(such as i want md5_url = md5(url_column_value)
I have known 2 way to set default value.
$table->string('md5_url')->default($value);
and
$stack_links = DB::table('stack_links')->update(['md5_url' => $value]);
but 2 above way, the $value is fix, how to make it flexible (diffirent in each row) so that i can add unique index after that.
Note: i don't want to create model StackLink so don't try this way:
$stack_links = StackLink::get();
foreach($stack_links as $stack_link) {
$stack_link->md5_url = md5($stack_link->url);
$stack_link->save();
}
Update: have try
$table->string('md5_url')->default(uniqid());
but it don't work too.The result is
Change your column property like this:
$table->string('md5_url')->nullable();
It's okay now!
Try IGNORE to set unique index to add new column.
public function up()
{
Schema::table('listings', function (Blueprint $table) {
$table->string('md5_url');
});
DB::statement('ALTER IGNORE TABLE listings ADD UNIQUE INDEX myindex (md5_url)');
}
public function down()
{
Schema::table('listings', function (Blueprint $table) {
$table->dropColumn('md5_url');
});
}

Insert a field with value whenever new instance of modal is created

I want to insert a field with value whenever new row is created for a modal.
Ex: Suppose this is my user.php modal
class User extends Authenticatable
{
protected $guarded = ['id'];
}
What i want is in my application anywhere when i insert a row in user table, then i want to insert an extra column code with its value in user table.
Ex: If i do below in my application
User::create(['name'=>'xyz', 'password' => 'kajsndjk']);
then it should insert an extra column code =>'Qwedf' also in my table.
In my application there are many places where i am creating the users, so i don't want to remember every time to insert code column.
Please suggest how can i achieve it.
Overriding the static create function on the User class is the only thing that will work in my opinion.
public static function create(array $attributes = [])
{
$object = parent::create($attributes);
$object->code = 'some text';
$object->save();
return $object;
}
I've tested and like I expected, oseintow's answer will not work, because it would work only if you directly modified code variable, which you obviously are not doing.
Add this mutator to your User model
public function setCodeAttribute($value)
{
$this->attributes['code'] = "Qwedf";
}
Anytime you are saving a record code will be assigned the Qwedf value

Use a column value in an other table with laravel query builder

I have two table witch named users & Inbox
In the Inbox table I have a column named sender_id that have the user_id of the sender
I want to show this message in the view. I need a query to get the sender_id from the inbox table and use that to select a certain user from the users table
I need to do this with all messages and all users.
Laravel is basicly straith foward when you use eloquent. You can always customise it.
First, almost all the time, I create a model and a migration at the same time using this : php artisan make:model Something --migration
I know you already make some models and/or migrations, but I'll go step by step to help you understand it.
So, in your case, it'll be php artisan make:model User --migration and php artisan make:model Inbox --migration. Doing this, you get two model named User and Inbox and two migration named date_create_users_table.php and date_create_inboxs_table.php. Maybe you already did the default user table with php artisan make:auth. If it's the case, don't remake one.
I'm not sure about how laravel will name the Inbox model migration... Since, I think, Laravel 5.3, the plurialisation changed and don't always just add an "S" at the end.
Then, now you got your models and migrations, let's add some line into your migration files. Since you want to do a one to many relationship. You don't need to touch the user one. Only the Inbox migration. Each Inbox is related to one User and Users can have many Inboxs. Add something like this in your migration:
public function up()
{
Schema::create('inboxs', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id');
$table->foreign('user_id')->references('id')->on('users');
all other columns...
});
}
There, you can change the column's name if you need to have a sender, a recipient, etc... Do this instead :
public function up()
{
Schema::create('inboxs', function (Blueprint $table) {
$table->increments('id');
$table->integer('sender_id');
$table->foreign('sender_id')->references('id')->on('users');
$table->integer('recipient_id');
$table->foreign('recipient_id')->references('id')->on('users');
all other columns...
});
}
What we just did, it's creating the Foreign key that Laravel will use to build the query. There is one last part before the fun one. We need to create the relation in our Model. Begin with the user one:
App/User.php
public function inboxs() {
return $this->hasMany(Inbox::class);
}
And now into the App/Inbox.php model:
public function user() {
return $this->belongsTo(User::class);
}
If you need to have a Sender/Recipient/etc... go this way instead:
public function sender() {
return $this->belongsTo(User::class);
}
public function recipient() {
return $this->belongsTo(User::class);
}
Note that each of your function need to be writen in the same way it's into your migration. sender_id need a relation named sender().
Now, that our relations are done, we can simply call everything using eloquent.
$inboxs = Inbox::with('sender')->get();
This will return an array of all your Inbox into the inboxs table. You can access the sender this way: $inboxs[0]->sender();
You need the id, do this: $sender_id = $inboxs[0]->sender_id;
The sender name : $sender_name = $inboxs[0]->sender->name;
If you want to get one Inbox and you have the id, just do this $inbox = Inbox::with('sender')->find($id);
This way you don't get an array, only one result and can access the sender directly using $sender_name = $inbox->sender->name; instead of having to add [0] or using a foreach loop.
You can get all messages sended by a user using something like this:
$inboxs = Inbox::where('sender_id', $sender_id)->get();
Finally, you can pass your data to the view using:
return view('path.to.view')->with('inbox',$inbox);
Into the view you do this to show the sender's name:
//If view.blade.php
{{$inbox['sender']['name']}} //work a 100%
{{$inbox->sender->name}} //I'm not sure about this one
//If not using blade
<?php echo $inbox['sender']['name']; ?>
There is a lot of thing you can do using Eloquent and you can add as much condition you want. The only thing I suggest you to really do if you want to use Eloquent, be aware about the n+1 problem. There is a link where I explain it. Look for the EDIT section of my answer.
If you need some documentation:
Laravel 5.3 Relationships
Laravel 5.3 Migrations
Laravel 5.3 Eloquent
I think you should update your code like:
$user_messages = DB::table('messages')
->select('messages.id as msgId','messages.message as message','users.id as userId','users.user_name as user_name')
->join('messages','messages.user_id','=','users.id')
->where('messages.user_id',$user_id)
->get();
return view("view.path")
->with('messages',$user_messages);
Hope this work for you!
In Model :
namespace App;
use Illuminate\Database\Eloquent\Model;
class Messages extends Model
{
protected $table = 'table_name';
public function sender()
{
return $this->belongsTo('App\User', 'sender_id', 'id');
}
}
In Controller :
public function functionName($user_id){
$messages = Messages::where('sender_id', $user_id)->get();
return view("view.path")
->with('messages',$messages);
}
In view, you can access seder details like this $message->sender->name for name for id $message->sender->id

Incorrect value for column with Laravel 4

I have a column created as follows in my Laravel 4 migration:
public function up()
{
Schema::create(
'templates',
function (Blueprint $table) {
$table->increments('id');
// Omitted fields...
$table->smallInteger('pages')->default(0);
$table->timestamps();
$table->softDeletes();
}
);
}
When I try to save the entity using
$entity->save();
in my controller, I get an error for that particular column when the field value is empty:
SQLSTATE[HY000]: General error: 1366 Incorrect integer value: '' for column 'pages' at row 1
I can fix this by creating a mutator in the model like so:
public function setPagesAttribute($value)
{
if (empty($value)) {
$this->attributes['pages'] = 0;
}
}
But isn't Laravel / Eloquent supposed to be doing that in any case?
I'm just thinking, I'm doing something wrong here...
I've discovered a solution online: http://www.garethalexander.co.uk/tech/mysql-5-incorrect-integer-value-column-id-row-1
Simply do the following:
edit my.cnf
comment out the line
sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
And run $ mysql.server restart
The problem is that an empty string is getting passed to the query for the Pages field (the default will only trigger if there's no value being passed for the field). I'm not sure how you're building your entity object, but you basically shouldn't be setting entity->pages at all when you want it to use the default value.
If you're getting pages via Input variables, using either Input::get('pages', 0) or Input::get('pages', null) should fix the problem.