How to add new fields to an existing index? - tarantool

I already have a space with some indexes.
box.schema.sequence.create('user_seq')
box.schema.space.create('user', {
if_not_exists = true,
format = {
{ name = 'id', type = 'unsigned'},
{ name = 'user_id', type = 'string'}
}
})
box.space.user:create_index('id', {
sequence = 'user_seq',
parts = {'id'}
})
box.space.user:create_index('user_id', {
parts = {'user_id'},
if_not_exists = true,
unique = false
})
Want to add new fields into user_id index. What I should do?

Consider usage of index.alter function (https://www.tarantool.io/en/doc/latest/reference/reference_lua/box_index/#box-index-alter)
E.g. you want to add "id" field to your "user_id" index.
box.space.user.index.user_id:alter({
parts = {
{field = 'user_id', type = 'string'},
{field = 'id', type = 'unsigned'}}, -- Add "id" field to your index
})
or e.g. you want to add new field to your schema and then to schema (e.g. "name").
Firstly, you should update your format:
box.space.user:format({
{ name = 'id', type = 'unsigned'},
{ name = 'user_id', type = 'string'}, -- Preserve to existing fields
-- Add a new one
-- It's important to define them as nullable because
-- you don't have them physically
-- If you want to define them as non-nullable
-- You should append "name" to each tuple before
-- It's possible because format checks only defined fields
-- But basically tuple is a list of values and
-- it can have arbitrary length.
-- For simplification I say it as nullable.
{ name = 'name', type = 'string', is_nullable = true},
})
-- Then you can to alter your index
box.space.user.index.user_id:alter({
parts = {
{field = 'user_id', type = 'string'},
{field = 'name', type = 'string', is_nullable = true},
},
})
Also I see you use parts = {'id'} and parts = {'user_id'}. It's a correct way to define indexes - provide an array of fields that should be indexed. But it makes your schema less expressive and allows you to make a mistake. Instead of it I suggest you to use strict schema definition. - specify parts explicitly {field = <field_name/field_number>, type = <type>, collation = <collation>, is_nullable = <true/false>}. You can omit type specification if format is already defined.
As shows the second example it's important. You can't specify parts={'user_id', 'name'} with is_nullable=true flag.

Related

create a list of data with value from multiple one to many relationsship

I have the table structure with the list of the id's selected from the drop down.
Lets say in the following format:
id,teacher_id,batch_id,course_id,program_id,depart_id
this fields get saved to database through ajax call. Now i wanted to get the name associated with this id's
I have a function Like this:
public function store(StoreEmployeesRequest $request)
{
$teacherCourse = TeacherCourse::create($request->all());
}
Here, after the TeacherCourse has been created, i wanted to get all the value associated with $teacherCourse->teacher_id from table TeacherCourse
and merge the value and create the array in the following format:
{
"id":8,
"program":"Master of Computer", //with program_id from program table
"course":"software engineering" //with course_id from course table
},
{
"id":7,
"program":"Bachelor of Pharmacy", //with program_id from program table
"course":"Structure Programing" //with course_id from course table
}
Relationship in TeacherCourse
public function course()
{
return $this->belongsTo(Course::class,'course_id');
}
public function program()
{
return $this->belongsTo(Program::class,'program_id');
}
I was trying to get the value using this operation but failed. How can i create a single array by getting the value from multiple table?
$teacherCourse = $teachercourse->program->map(function ($program)
{
return $program->name;
});
try this:
$teacherCourse = $teachercourse->map(function ($teacherCourse)
{
return [
'id' => $teacherCourse->id,
'program' => $teacherCourse->program()->pluck('name'),
'course' => $teacherCourse->course()->pluck('name');
];
})->toArray();
I hope help you

yii2 Validation not working

I need to validate a value from another table both of them field type decimal
if amount(model 1) moreover available(model2 DATA selected)
model 1
rule
public function rules()
{
return [
[['amount'], 'checkAvailable','skipOnEmpty' => false],
];
}
custom validation function
public function checkAvailable($attribute, $params)
{
$caid = $this->capex_budget_id;
$available = Capexbudget::find()
->select(['available'])
->where('id = :caid', [':caid' => $caid])
->all(); // select amount from Capexbudget where id = $caid
if ($this->amount > $available){
$this->addError('amount', 'not enough');
}
}
i can got a data available from Capexbudget where ID that i select
here are the query logs
but validation not working it not compare value between $this->amount and $available
what i missing please.
First of all, you're selecting all records matching your where conditions here:
$available = Capexbudget::find()
->select(['available'])
->where('id = :caid', [':caid' => $caid])
->all(); // HERE
You should change function all() to one(), to get one record.
Second thing is, if you're using all() or one(), that methods returns object, not value.
To make it work, you should change if statement to:
if ($this->amount > $available->available){ //here, compare to attribute `available`

Distinct values with pluck

I'm trying to retrieve data from database and bind them to a html select tag, and to bind them i need to use pluck so i get the field i want to show in a array(key => value), because of FORM::select. The normal pluck gets all the results, while i want to use distinct. My model is Room and it looks like:
class Room extends Eloquent
{
public $timestamps = false;
protected $casts = [
'price' => 'float',
'floor' => 'int',
'size' => 'float'
];
protected $fillable = [
'capacity',
'description',
'price',
'floor',
'size',
'type',
'photo_name'
];
}
While my function I'm using in the controller look like:
public function getRooms()
{
$roomType = Room::pluck('type','type');
$roomFloor = Room::pluck('floor','floor');
return view('roomgrid')->with('type',$roomType)->with('floor',$roomFloor);
}
And my view contains this piece of code to get floors:
{{FORM::select('floor', $floor, null,['class'=>'basic'])}}
Like this i get duplicated floors, that i don't want. Is there any way so i can get distinct floors and pluck them? Thanks in advance.
Why not use groupBy()?
$roomType = Room::groupBy('type')->pluck('type','type');
Room::unique('floor')->pluck('floor', 'floor');
distinct can do the trick:
Room::query()->distinct()->pluck('type');
Which will be translated into the following SQL:
SELECT DISTINCT type FROM rooms
2019 Update
You don't need to use 2 arguments with pluck()
simply do:
$roomType = Room::groupBy('type')->pluck('type');
of course for getting it into array:
$roomType = Room::groupBy('type')->pluck('type')->toArray();
Sometimes I use the result for whereIn clause, its useful for that.
you can do this
$roomType = Room::pluck('type')->unique();
$roomFloor = Room::pluck('floor')->unique();
You can use KeyBy or pluck with same key-Value pair to pick Distinct Values.
PHP array can only have unique keys.From this Idea we can get Unique models based on Array key.
Room::keyBy('floor')->pluck('floor');
or
Room::pluck('floor', 'floor');

Return dummy info from laravel relationship

In laravel we specify foreign keys this way
public function creator() {
return $this->belongsTo('App\Models\User', 'creator_id', 'id');
}
Is there some way to return dummy user ('system') when creator_id is null?
Reason: to display it in template.
For example:
If creator_id = 10 => creator = {id: 1, name: 'John'}
If creator_id = null => creator = {id: 0, name: 'system'}
Try this in your template :
{{ (model->creator) ? model->creator->name : 'system' }}
model will replace with your variable name.
Create a dummy user with id = 0 and name = 'System'.
Give the creator_id a default value of 0 in the migration

Symfony2 constraints entity validation yml

I've a many to many relation (user and account). In the user entity, I've private property groups (array collection).
When I try to validate this property (groups) with a simple "NotBlank", it's not work. So I try this below (collection and choice).
I read this http://symfony.com/fr/doc/2.3/reference/constraints/Choice.html
and this http://symfony.com/fr/doc/2.3/reference/constraints/Collection.html but it doesn't work or I don't correctly use them.
Can anybody gives me some help ?
/* USER accounts property
...
/**
* #ORM\ManyToMany(targetEntity="Account", mappedBy="users", cascade={"persist", "remove"})
*/
private $accounts;
...
Than the userType
...
->add('accounts', 'genemu_jqueryselect2_entity', array(
"class" => "CMiNewsBundle:Account",
"property" => "name",
"multiple" => "true",
"query_builder" => function (EntityRepository $er) use ($user)
{
return $er->createQueryBuilder('acc')
->join('acc.users','u')
->where('u.id = :userID')
->setParameter('userID' , $user);
}
)
)
...
The validation.yml
CM\Bundle\iNewsBundle\Entity\User:
properties:
...
accounts:
- NotBlank: ~
...
"NotBlank" assert checks if the property === null || property === ''. Since your property is a collection, you probably initialise it as an ArrayCollection in your constructor so it will never be null.
For collections you should use the "Count" assert
http://symfony.com/doc/current/reference/constraints/Count.html
It forces you to set the "maximum" count as well as the minimum so you might want to create your own assert.

Resources