Yii2 : how to check value is unique with below scenario - yii2

my table and its data
id |type | email
1 |1 | user1#domain.com
2 |1 | user2#domain.com
3 |2 | user3#domain.com
4 |2 | user4#domain.com
5 |2 | user5#domain.com
Their is lots of type 1,2,3,4,5,..
All TYPE has dublicate emails except type 2
but,I want to make column email unique only for type 2
using yii2 model validation

You can use filter and try something like this, not tested though
['email', 'unique', 'targetClass' => Model::className(), 'filter' => function ($query) {
return $query->andWhere(['type' => 2]);
}],

Related

Making a tree with MySQL datas

I have a MySQL table like this:
+------+-----------------+---------+------------+
| id | name | refferal| reference |
+------+-----------------+---------+------------+
| 1 | Alex Muller | 1 | null |
| 2 | John Doe | 2 | 1 |
| 3 | Tom Foe | 3 | 1 |
| 4 | Harry Pott | 4 | 3 |
| 5 | Kate Garry | 5 | 3 |
| 6 | Mike Blue | 6 | 4 |
+------+-----------------+---------+------------+
(more data than this...)
I need to turn that data to JSON file with Laravel. Like this:
[{"id":1,"name":"Alex Muller","parent":0},
{"id":2,"name":"John Doe","parent":1},
{"id":3,"name":"Tom Foe","parent":1},
{"id":4,"name":"Harry Pott","parent":3},
{"id":5,"name":"Kate Garry","parent":3},
{"id":6,"name":"Mike Blue","parent":4}]
At the and of this I will get a tree view like this:
TREE
I just made this json file with my own write. And I don't know what to do. I'm waiting your answers. Thank you.
If you want to add extra fields like "parent" in your example you can use map on the collection:
$users = User::where(function($query){
...
})->get()->map(function($user){
return array(
"id" => $user->id,
"name" => $user->name,
"parent" => *INTEGER*
);
})->toJson();
Or if you just want to encode the model attributes, you can use toJson serialization directly with the collection:
$users = User::User::where(function($query){
...
})->get()->toJson();
for further information, refer to the links:
https://laravel.com/docs/collections
https://laravel.com/docs/eloquent-serialization#serializing-to-json
On the model get the keys you need and then with map() change the key reference to parent, on that check if is null the reference to put a 0 then encode the array for json with json_encode.
$array = Model::get(['id', 'name', 'reference'])
->map(function($model){
return [
'id' => $model->id,
'name' => $model->name,
'parent' => is_null($reference->reference)? 0 : $reference->reference,
];
})
->toArray();
Then just make a json with that array:
echo json_encode($array);

How can I create a virtual summation field by entity

I have records which have a sq. mileage field. I want to sum these fields by date, so regardless of display page, order, etc. the value by entity will be the same.
e.g.:
|id| date |sqmiles|total|
|--|----------|-------|-----|
|1 |2010-10-10| 2 | 2 |
|2 |2011-11-11| 3 | 5 |
|3 |2012-12-12| 1 | 6 |
|id| date |sqmiles|total|
|--|----------|-------|-----|
|3 |2012-12-12| 1 | 6 |
|1 |2010-10-10| 2 | 2 |
|2 |2011-11-11| 3 | 5 |
My starting thoughts were a virtual field where it requests the following SQL:
SELECT SUM(sq_miles) FROM table WHERE date <= ($this->_properties['date']); but with CakePHP3's new ORM I don't know how to put that into code.
This may not be the "best" answer, but I made it work:
In the entity add use Cake\ORM\TableRegistry; then the following function:
protected function _getTotalSqMiles()
{
$annexations = TableRegistry::get('Annexations');
$query = $annexations->find();
$sum = $query->func()->sum('sq_miles');
$results = $query->select(['total' => $sum])
->where([
'effective_date <=' => $this->_properties['effective_date']
])
->first();
return $results->total;
}

Sqlalchemy/marshmallow single Code table join

I am implementing flask rest API with existing database. The db contain one common look up table, where multiple look up is separate by code categories.
Id = Primary Key , tablename = "CommonCode"
|id | code_category | codeValue | CodeDesc
------------------------------------------
|1 | "season" | "1" | "Summer"
|2 | "season" | "2" | "Winter"
|3 | "status" | "1" | "Success"
|4 | "status" | "2" | "Fail"
|5 | "Deleted" | "Y" | "Yes"
|6 | "Deleted" | "N" | "No"
I have many tables that referencing to the "CommonCode"
When I try too reference using the code below, it will return the ID instead of the "Code Desc" column,
I am using marshmallow. If specifying the column, ItemTypeDesc = field_for(CommonCode, 'CodeDesc')
the object will be return "<Model.xxxx.CommonCode object at 0x00F8D710>.
Is there recommended approach to implement common code table in sqlalchemy/marshmallow?
.
ItemType = db.Column(db.String(2),db.ForeignKey('CommonCode.codeValue'))
ItemTypeDesc = db.relationship("CommonCode",
primaryjoin="and_(Othertable.ItemType==CommonCode.codeValue, "
"CommonCode.Code_Category=='season')",
collection_class=attribute_mapped_collection('CodeDesc'))

How to create custom column in Yii2 grid view by using other table value

Suppose I have table A and B.
Table A contain column id, name
id | name
----|-----------
1 | X
2 | Y
3 | Z
Table B contain column id, tax_type, rate
id | tax_type | rate
----|-----------|--------
1 | services|12
2 | vat |3
3 | others |4
I have created grid view using table B, so the column of grid view are id and name.
But I want column dynamically in grid view by fetching table B values.
Like:
id | name |services | vat | others
----|-------|-----------|-------|--------
1 | X | 12 | 3 | 4
2 | Y | 12 | 3 | 4
3 | Z | 12 | 3 | 4
If the row change in table B then columns are also change in grid view.
Your Gridview columns can have any value. Do the following in your view:
First, get your data from table B:
$taxInfo = TableB::find()->indexBy('tax_type')->all();
Then, in your view in column definitions just add this:
'columns' => [
'id',
'name',
//...
[
'label' => 'Services',
'value' => function ($model) use $taxInfo {
$taxInfoObject = $taxInfo['services'];
return $taxInfoObject->rate;
}
],
[
'label' => 'VAT',
'value' => function ($model) use $taxInfo {
$taxInfoObject = $taxInfo['vat'];
return $taxInfoObject->rate;
}
],
[
'label' => 'Others',
'value' => function ($model) use $taxInfo {
$taxInfoObject = $taxInfo['others'];
return $taxInfoObject->rate;
}
],
]
Note how the $taxInfo variable we defined above is passed to our anonymous functions. (Generally those functions work with $model which, in your case, would contain a specific row of table A).

DataMapper ORM relationships

table1(users)
|ID|name |type |
|1 |demo |admin |
|2 |demoX |client|
table2(visits)
|ID|admin_id|visitor_id|visit_date|...
|1 |1 |2 |2013-01-01|...
admin(fk)->users(id)
user(fk)->users(id)
simple scheduler project, it contain 2 tables.
1st (users) contain all users, 2nd table contain all bookings(visits).
to get all bookings of an admin i run Select * from visits where admin_id=$id;, and join
visitor info from users table.
........
so basically,
every admin can have many visit
visit must contain (ONE)admin and (ONE)visitor.
how can i setup this kind of relation in datamapper orm ?
This should do it:
class Users extends Datamapper
{
public $has_many = array(
'admin' => array(
'class' => 'users',
'other_field' => 'admin', // FK = admin_id
),
'visitor' => array(
'class' => 'users',
'other_field' => 'visitor', // FK = visitor_id
),
);
}
class Visits extends Datamapper
{
public $has_one = array(
'admin' => array(
'class' => 'users',
'join_self_as' => 'admin', // FK = admin_id
),
'visitor' => array(
'class' => 'users',
'join_self_as' => 'visitor', // FK = visitor_id
),
);
}
// then in your controller you can do:
$visit = new Visitor(1);
echo $visit->admin->name; // echo's 'demo';
echo $visit->visitor->name; // echo's 'demoX';
First of all I think, instead of having a table with admin_id and user_id (isn't helpful), you should have a separate table with users and privileges, then the table structure would be.
Users privileges
| id | user | privilege_id | | id | privilege |
| 1 | user1 | 1 | | 1 | user |
| 2 | admin1 | 2 | | 2 | admin |
Then when you are calling the user level within the application just:
SELECT privilege FROM privileges WHERE id = <privilege_id from users table which should already be set within your code> (MySQL)
you should ALWAYS try and set id's in your tables for this purpose, this will be the basis of your relationship data when your gathering data from another table, so in this example it will be the <id> field of the privileges table and the <privilege_id> of the users table.
From here you should be able to transfer this method across to Datamapper or codeigniter or whatever your misleading tags mean =]
if you need to SELECT a booking from a database, select the booking(make an additional table and append as below) and look for the times of the bookings where ((privilage_id == 1) && (privilage_id == 2)) this will look for the dates where there is both a admin and a user, instead of just looking at one user type you are looking at them all and also saving yourself some hassle by making the call to one column rather than several. also this way you can easily manage your tables as their names relate to there function.
Users privileges booking
| id | user | privilege_id | | id | privilege | | id | date | privilege_id |
| 1 | user1 | 1 | | 1 | user | | 1 |5/2/13| 1 |
| 2 | admin1 | 2 | | 2 | admin | | 2 |5/2/13| 2 |
so the MySQL would be SELECT date FROM booking WHERE ((privilege_id == 1) && (privilege_id == 2)) this will give you the results you would expect, if you need to sanitise your data to go into the tables then you would require two rows to be made in one database which would be done by a procedure like this (this example will use an imaginary filled booking form(and is done in PHP)):
if((isset($user) && (isset($usertype)) && (isset($usertypetwo)) && (isset($date)))
{
if(($usertype != $usertypetwo))
{
"Insert BLAH BLAH"
}
}
also remember using this method you will need to get the user type from the user table to get the privilege_id