Yii Get data from another model using Relation - php

I am trying to filter a table in my view using the search function in my model.
I have two models which i need to get data from model Evaluation to another model EvaluationDetails.
i have this in my EvaluationDetails model
public function relations() {
return array(
'eval' => array(self::BELONGS_TO, 'Evaluation', 'eval_id'),
);
}
i also have this in my search function
public function search($employee = '', $search_date_start = '', $search_date_end = '', $search = '') {
$criteria = new CDbCriteria;
$criteria->with = array('eval' => array('together' => true));
$criteria->compare('employee_id', $this->employee_id);
$criteria->compare('remarks', $this->remarks, true);
$criteria->compare('eval_id', $this->eval_id);
$criteria->compare('eval.evaluatee', $this->evaluatee_search);
$criteria->addSearchCondition('eval.evaluatee', $search);
if ($employee != '')
$criteria->compare('employee_id', $employee->company_id);
return new CActiveDataProvider($this, array(
'criteria' => $criteria,
));
}
I am trying to filter a table where in the user will search for a name, pass the value in $search which is then used in the search function in my EvaluationDetails model
With this, i am getting an error.
CDbCommand failed to execute the SQL statement: SQLSTATE[23000]:
Integrity constraint violation: 1052 Column 'employee_id' in where
clause is ambiguous. The SQL statement executed was: SELECT
COUNT(DISTINCT t.id) FROM trx_evaluation_details t LEFT OUTER
JOIN trx_evaluation eval ON (t.eval_id=eval.id) WHERE
((eval.evaluatee LIKE :ycp0) AND (employee_id=:ycp1))
what seems to be the problem with my code. please help..

Seeing from the error message, it looks like both EvaluationDetails and Evaluation have a field call "employee_id" (i am not sure)
But if so, you need to replace the
$criteria->compare('employee_id', $employee->company_id);
with
$criteria->compare('t.employee_id', $employee->company_id);
To explicitly tell yii the field is from EvaluationDetails table.
BTW, u are using $employee->company_id (should be $employee->employee_id ?)

Related

Query in Yi2 and checking a relationship in another table

I am trying to get data in a Yii2 table call Post. This table has an attribute call owner and I want to check whether the value of owner is equal to a particular Value I pass call it userId or the value of owner is equal to the following attribute of the Followship table where the value of the follower attribute of the Followship Table is equal to the the value I pass call it userId.
In implementing the above logically and bit by bit, I have written the following code;
$allpost = Post::find()->all();
$relevantpost = [];
foreach ($allpost as $post) {
if($post->owner == $userId){
$relevantpost[] = $post;
}
else{
$follower = Followship::findOne(['follower'=>$userId, 'following'=>$post->owner]);
if($follower){
$relevantpost[] = $post;
}
}
}
return $relevantpost;
This code works well but I want to write an active query for this such as ;
$allpost = Post::find()
->where(['owner'=>$userId])
->orWhere(['is NOT', $follower = Followship::findOne(['follower'=>$userId]) and 'owner' => $follower->following, NULL])
->all();
or in the worse case,
$allpost = \Yii::$app->db
->createCommand(
"SELECT postId, location, details, created_at FROM Post
WHERE owner = " . $userId. "OR
owner = '0' OR
owner = following IN (
SELECT following FROM Followship WHERE follower = ". $userId . " AND
)
ORDER BY dateCreated DESC"
)
->queryAll();
I keep getting errors with the above queries. I am missing out a fundamental of the Yii2 query builders.
Please any help on this will be greatly appreciated.
First you could make a relation (which connects Post and Followers by post owner) inside your Post class
class Post extends ActiveRecord {
public function getFollowersDataset() {
return $this->hasMany(Followers::className(), ['following' => 'owner']);
}
...
}
And then you can just use it in your queries
Post::find()
->joinWith('followersDataset')
->where(['or',
['owner' => $user_id],
['follower' => $user_id]])
->all()
The condition accept three parameters
[the_condition, the_attribute, the_value]
In case of AND and OR the thing change
[the_condition, first_condition, second_condition]
With the second tried you can make something like that
$allpost = Post::find()
->where(['owner'=>$userId])
->orWhere([
'AND',
['is NOT', $follower, Followship::findOne(['follower'=>$userId]),
['owner', $follower->following, NULL]
])
->all();
You can check in debug bar the querys that you're making, or another way, its to make a mistake in a field, for example if in your where condition you put ->where(['owners'=>$userId]), that trhow an error with the query that you made, so you can see what query you did

select relations from MANY to MANY in yii framework using Criteria

I have a table Policy which links to another table Currency and the relation is as below:
'policyCurrency' => array(self::MANY_MANY, 'Currency', 'policy_currencies(PolicyId, CurrencyId)’),
I am also using the search function provided in the model to get the data and I want to select the Currency which resides in the related Currency Table as part of the search. Below is my search function.
public function search(){
$criteria = new CDbCriteria;
$criteria->compare('PolicyId', $this->PolicyId);
$criteria->compare('Name', $this->Name, true);
$criteria->compare('Amount', $this->Amount, true);
return new CActiveDataProvider($this, array( 'criteria' => $criteria));
}
When using the search getData:
$result = Policy->search()->getData();
The result returned is in the format of:
PolicyId = 1
Name = 'Test'
Amount = '20'
etc etc etc
I want the data related to the relations which is currency in this case be returned as part of the select like this (appending one after the other separated by a ',' since this is a MANY to MANY relation):
CurrencyId = 1,2,3
What I have tried:
Trying to use the
$criteria->with = array('policyCurrency');
$criteria->together = true;
but i am confused about how to use select to select all records from the first table Policy in my case and all related CurrencyIds seperated by a ',' from the related model.
Thanks
You need to add the relation name to the with attribute so it does a JOIN with Currency and gets all its related data:
public function search(){
$criteria = new CDbCriteria;
$criteria->with = array('policyCurrency');
For more info, check CDBCriteria documentation.

Advanced search is not functional for two fields

I am stuck with an issue regarding searching functionality.I am using PHP and Yii framework. I have a search option in my grid view which has 5 fields with drop down menu, 3 field in the search form are working only two fields are not working....I don't know why..I have written a search function in my model.
Model:
public function searchByManager($id)
{
$User =new User;
$criteria=new CDbCriteria;
$criteria->with=array('user');
$criteria->condition = "user.supervisor_id = $id";
$criteria->compare('user_id',$this->user_id);
$criteria->compare('job_title_id',$this->job_title_id);
$criteria->compare('cv_type',$this->cv_type,false);
$criteria->compare('review_status',$this->review_status,true);
$criteria->compare('is_current',$this->is_current,true);
$criteria->addInCondition("is_current", array("yes"));
//$criteria->condition = "cv_upload.is_current = yes";
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
'sort'=>array(
'defaultOrder'=>'upload_date DESC'
)
));
}
user_id and job_title_id these two fields are not working...when I search by them it shows an error something like this:
CDbCommand failed to execute the SQL statement: SQLSTATE[23000]:
Integrity constraint violation
Can anyone please help me out.

CakePHP3 custom finder method using contain and does not work when attempt to display the associated model field

This is my custom finder method inside DynamicViewsTable.php
public function findAccessibleByUser(Query $query, array $options)
{
if (empty($options['User']['id'])) {
throw new Exception("Current User not set", 1);
}
$query->select(['DynamicViews.id', 'DynamicViews.title', 'UsersAccessDynamicViews.ordinal_ranking'])
->contain(['UsersAccessDynamicViews'])
->where([
'UsersAccessDynamicViews.user_id' => $options['User']['id'],
])
->order(['UsersAccessDynamicViews.ordinal_ranking' => 'ASC']);
return $query;
}
The error I keep getting is:
Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'UsersAccessDynamicViews.ordinal_ranking' in 'field list'
and the query shown in the error page is:
SELECT DynamicViews.id AS `DynamicViews__id`, DynamicViews.title AS `DynamicViews__title`, UsersAccessDynamicViews.ordinal_ranking AS `UsersAccessDynamicViews__ordinal_ranking` FROM dynamic_views DynamicViews WHERE UsersAccessDynamicViews.user_id = :c0 ORDER BY UsersAccessDynamicViews.ordinal_ranking ASC
DynamicViews hasMany UsersAccessDynamicViews
While you can include any type of associaition using contain(), matching something does only work for 1:1 and n:1 associations, that is hasOne and belongsTo, as these are the only associations where contain() will join in the related tables.
For all other purposes you will have to use either matching() (requires a recent dev snapshot in order to work when combined with contain(), escpecially for more complex combinations)
$query
->select(['DynamicViews.id', 'DynamicViews.title', 'UsersAccessDynamicViews.ordinal_ranking'])
->contain(['UsersAccessDynamicViews'])
->matching('UsersAccessDynamicViews', function ($q) use ($options) {
return $q->where([
'UsersAccessDynamicViews.user_id' => $options['User']['id']
]);
})
->order(['UsersAccessDynamicViews.ordinal_ranking' => 'ASC']);
join in the related tables manually:
$query
->select(['DynamicViews.id', 'DynamicViews.title', 'UsersAccessDynamicViews.ordinal_ranking'])
->contain(['UsersAccessDynamicViews'])
->innerJoin('UsersAccessDynamicViews', [
'UsersAccessDynamicViews.dynamic_view_id = DynamicViews.id',
'UsersAccessDynamicViews.user_id' => $options['User']['id']
])
->order(['UsersAccessDynamicViews.ordinal_ranking' => 'ASC']);
or query from the other table.
See also
http://book.cakephp.org/3.0/en/orm/retrieving-data-and-resultsets.html#filtering-by-associated-data
http://book.cakephp.org/3.0/en/orm/query-builder.html#adding-joins

Laravel - Query just one row in a pivot table and return all data within the relationship

Currently, a criteria BelongsToMany alerts and viceversa. They are related through a pivot table: criteria_id and alert_id.
I am getting all Criteria with the associated Alerts that belongs to the authenticated user, as such:
public function getMatches()
{
$matches = Criteria::whereUserId( Auth::id() )
->has('alerts')
->get();
}
This returns all associated results, whereas now, if a user picks a certain result, I want to be able to show just that. This is what I have so far:
Controller
public function getMatchDetails($alert_id, $criteria_id)
{
$matches = Alert::find($alert_id)
->has('criterias')
->where('criteria_id', $criteria_id)
->get();
}
Which is bringing over the correct variables, however, I am getting a MYSQL error:
Column not found: 1054 Unknown column 'criteria_id' in 'where clause'
select * from `alerts` where `alerts`.`deleted_at` is null and
(select count(*) from `criterias` inner join `alert_criteria` on `criterias`.`id` =
`alert_criteria`.`criteria_id` where `alert_criteria`.`alert_id` = `alerts`.`id`)
>= 1 and `criteria_id` = 7)
Any help would be hugely appreciated.
You could try something like this
public function getMatchDetails($alert_id, $criteria_id)
{
$match = Alert::whereHas('criterias', function ($q) use ($criteria_id) {
$q->where('criteria_id', $criteria_id);
})->find($alert_id);
}
Which will find the alert by id and also check that it has a relationship to criterias meeting those requirements.
I don't know if I understood well the question, but I'm going to try to answer
If you want to pass more than just a variable from the view to the controller, you can do something like this:
View
#foreach($matches as $match)
#foreach($match->alerts as $alert)
<td>{{$alert->pivot->criteria_id}}</td>
<td>{{$alert->id}}</td>
#endforeach
#endforeach
Controller
public function getMatchDetails($id, $var_2 = 0)
{
$myCriteriaIds = Criteria::whereUserId( Auth::id() )
->lists('id');
$match = Alert::find($id)->criterias()
->wherePivot('criteria_id', 'IN', $myCriteriaIds)
->get();
}
Route
Route::post('/users/alert/matches/{id}/{var_2}', array(
'as' => 'users-alert-matches',
'uses' => 'XXXController#getMatchDetails'
));

Categories