How to display value from other table using primary key - php

I have implemented my project in Yii. I displaying search results in view part.
I wrote a search query for fetching the results from one table which is Recipe.
In this table name, course_id, cuisinename,type, colorie_count respectively, course_id,cuisinename, type are columns respectively.
In my controller i write code like this:
$result="SELECT * FROM recipe WHERE name LIKE '%$name%' AND `cuisinename` LIKE '$cuisine1%' AND course_id LIKE '%$course1%' AND `type` LIKE '%$type1%' AND `calorie_count` LIKE '%$calorie1%' ORDER BY recipe_id DESC LIMIT 15";
values are getting. if i give condition based to display the search result text. not displaying all name.
but those are displaying based on names.
I added below my view part condition and code:
$query= Course::model()->find("course_id=$as1");
$course2=$query->course_name;
$query1= Cuisine::model()->find("id=$as4");
$cuisine2=$query1->cuisinename;
$query3= RecipeType::model()->find("id=$as3");
$type2=$query3->recipeType_name;
<?php echo '<p align="center"> Showing results for&nbsp:&nbsp'.'Name'.$getval.',&nbsp'.'Course-'.$course2.',&nbsp'.'Cuisine-'.$cuisine2.',&nbsp'.'Type-'.$type2;',&nbsp';'</p>';
echo ',&nbsp'.'Calories-'.$calorie;
?>

You need to create relations between tables look there. For Recipe model it should be
public function relations()
{
return array(
'cuisine'=>array(self::BELONGS_TO, 'Cuisine', 'cuisine_id'),
'type'=>array(self::BELONGS_TO, 'RecipeType', 'type_id'),
);
}
Then you can get values as $model->cuisine->name. If you don't understand creating relations, generate models (it tables must be correct foreign keys) with gii.

check this article: http://www.yiiframework.com/doc/guide/1.1/en/database.arr about relations in AR
class Recipe extends CActiveRecord
{
......
public function relations()
{
return array(
'course'=>array(self::BELONGS_TO, 'Course', 'course_id'),
'cuisine'=>array(self::BELONGS_TO, 'Cuisine', 'cuisine_id'),
'type'=>array(self::BELONGS_TO, 'RecipeType', 'type_id'),
);
}
}
and related Models
class RecipeType extends CActiveRecord
{
......
public function relations()
{
return array(
'recipes'=>array(self::HAS_MANY, 'Recipe ', 'type_id'),
);
}
}
and your search query will be smth like this in controller file:
$criteria=new CDbCriteria;
$criteria->with=array(
'course',
'cuisine',
'type',
);
$criteria->addCondition('course.course_id = :filter_course'); // for ID compares
$criteria->addSearchCondition('cuisine.name', $cuisinename) //for LIKE compares
...
$criteria->params = array(':filter_course' => intval($course1));
$searchResults = Receipe::model()->findAll($criteria);
and in your view you can get related tables values:
foreach ($searchResults as $result){
echo $result->cuisine->name;
}
check also http://www.yiiframework.com/doc/api/1.1/CDbCriteria for details
you can also use this $criteria to create DataProdier for CListView or CGridView helpers in your view file
$dataProvider=new CActiveDataProvider( Receipe::model()->cache(5000),
array (
'criteria' => $criteria,
'pagination' => array (
'pageSize' => 10,
)
)
);
$this->render('search',array(
'dataProvider'=>$dataProvider
));
http://www.yiiframework.com/doc/api/1.1/CListView/
http://www.yiiframework.com/doc/api/1.1/CGridView

Related

How to filter associated HABTM data with FriendsOfCake Search for CakePHP 3

Plugin: FriendsOfCake/Search
CakePHP: 3.1.4
I'm using the plugin to filter my index.ctp view data with a form.
This similar question:
How to Filter on Associated Data
is about a belongsTo association. My question is specifically about associated HABTM data where my associated table is linked through a joinTable and not directly. The normal setup in the Model like the following is not working in this case:
->value('painting', [
field' => $this->Paintings->target()->aliasField('id')
)]
My tables are set up like:
Tickets belongsToMany Paintings
Paintings belongsToMany Tickets
with joinTable tickets_paintings
Here is the main setup:
class TicketsTable extends Table
{
public function initialize(array $config)
{
...
$this->belongsToMany('Paintings', [
'foreignKey' => 'ticket_id',
'targetForeignKey' => 'painting_id',
'joinTable' => 'tickets_paintings'
]);
}
public function searchConfiguration()
{
$search = new Manager($this);
$search->value('status', [
'field' => $this->aliasField('active'),
])->like('member_name', [
'field' => $this->Members->target()->aliasField('surname'),
'filterEmpty' => true
])->value('painting', [
'field' => $this->Paintings->target()->aliasField('id'), // not working
]);
return $search;
}
class TicketsController extends AppController
{
public function index()
{
$query = $this->Tickets
->find('search',
$this->Tickets->filterParams($this->request->query))
->contain(['Members', 'Paintings', 'Appointments']);
...
}
Everything else is working and the parameters are added to the URL when I filter etc., so I only put in the parts where sth has to be wrong.
After filtering I get an error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'Paintings.id' in 'where clause'
The contain works properly when just displaying data from the Paintings table in the Tickets view.
But in the code from the SQL query I can see, that all contained tables (Members, Appoinments) are joined for the query except the Paintings table, so obviously it can not find the column...And I guess it can't really join it directly anyway since they are only connected through the joinTable.
I'm new to CakePHP and I can't really figure out what I'm doing wrong here, so hopefully someone can help me out a bit.
Do I have to use a different syntax in the plugin settings? Do I have to set up my Tables differently? Or how exactly can I tell the query to incorporate the habtm related table in the search?
Thanks!
The available search methods rely on the field being available in the main query (hasMany and belongsToMany associations are being being retrieved in separate queries).
While you could join it in manually in the controller, using a callback- or a finder-filter is probably the better approach, that way you can modify the query in the model layer, and you could easily utilize Query::matching() to filter by associated data.
Here's an (untested) example that should give you a hint:
use Cake\ORM\Query;
use Search\Type\Callback; // This changed in master recently
// now it's Search\Model\Filter\Callback
// ...
public function searchConfiguration()
{
$search = new Manager($this);
$search
// ...
->callback('painting', [
'callback' => function (Query $query, array $args, Callback $type) {
return $query
->distinct($this->aliasField('id'))
->matching('Paintings', function (Query $query) use ($args) {
return $query
->where([
$this->Paintings->target()->aliasField('id') => $args['painting']
]);
});
}
]);
return $search;
}
See also
https://github.com/FriendsOfCake/search/blob/9e12117404f824847b2d1aa093f3d52736b658b4/README.md#types
https://github.com/FriendsOfCake/search/blob/master/README.md#filters
Cookbook > Database Access & ORM > Retrieving Data & Results Sets > Filtering by Associated Data

how to join two tables in yii if i am querying a table using model and i don't want to use model for the second table?

Hi Guys i want to execute the following query
select tbl_workspace.wsName,tbl_cities.cityName from tbl_workspace JOIN tbl_cities on tbl_cities.id = tbl_workspace.city WHERE active=1;
The method in the controller is as follows
public function actionWork(){
$criteria=new CDbCriteria;
$criteria->order = 'sorter';
$criteria->condition = 'active=1';
$criteria->join= 'LEFT JOIN tbl_cities on tbl_cities.id = `t`.`city`';
$workspaceList = Workspace::model()->findAll($criteria);
$response=array();
$workspace=array();
$response['status']='True';
$response['WorkspaceList']=array();
if ($workspaceList):
foreach ($workspaceList as $row):
$workspace['id'] = $row['id'];
$workspace['wsName'] = $row['wsName'];
$workspace['city'] = $row['city'];
array_push($response['WorkspaceList'],$workspace);
endforeach;
endif;
echo CJSON::encode($response);
}
model for table tbl_workspace is defined in the Workspace model But i haven't used any model for tbl_cities and i want to get this value
tbl_cities.cityName , body of the method actionWork is defined in the controller and i want to query tbl_cities.cityNamein my $workspaceList Object. please help me guys
You must use Relational Active Record in yii. this is very simple and useful :
in models\WorkspaceList.php add:
public function relations() {
return array(
'cities0' => array(self::BELONGS_TO, 'Cities', 'city'),
)
}
Create Model with CRUD generator for Cities.
for access to this field $row->cities0->cityName or $row['cities0']->cityName
and in findAll:
Workspace::model()->with('cities0')->findAll();

Change yii crud generated page

I have 2 models: taxiDrivers and taxiOrders. In taxiOrders I have a field driver_id, but instead of just an id, I want to output driver's name (which is located in taxiDrivers). Both models are generated via gii, and crud tools are also generated. The page which is needed to be changed is taxiOrders/admin (view: admin.php, models: TaxiOrders.php, TaxiDrivers.php and respective controllers)
2 DCoder: Thanks dude! but one more query I have and hope you can clearify: I have a standart generated admin.php view page with following code:
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'taxi-orders-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
'id',
'uid',
'did',
'type',
'notes',
//'or_lat',
//'or_lng',
//'des_lat',
//'des_lng',
'cost',
'rating',
'date',
'time',
'status',
array(
'class'=>'CButtonColumn',
),
),
)); ?>
and below code is for controller:public function actionAdmin()
{
$model=new TaxiOrders('search');
$model->unsetAttributes(); // clear any default values
if(isset($_GET['TaxiOrders']))
$model->attributes=$_GET['TaxiOrders'];
$this->render('admin',array(
'model'=>$model,
));
}
So can u please show me where I could put your manipulations.
The Yii way would be to define a Relation between the two model classes (and enforce it with a Foreign Key). Then Yii would know how the two classes are related and you would have an easier time loading the related data.
In the TaxiOrders model class, a relation would look like this:
/**
* #property TaxiDrivers $Driver
*/
class TaxiOrders extends CActiveRecord {
// ...
public function relations() {
return array(
'Driver' => array(self::BELONGS_TO, 'TaxiDrivers', 'driver_id'),
);
}
// ...
}
In the controller, when you load the order data, you can prefetch the associated driver data like this:
public function actionOrderInfo($orderID) {
$order = TaxiOrders::model()->with('Driver')->findByPk($orderID);
// render it
}
with('Driver') will make sure that each returned order has its driver info already loaded, no matter if you need to find one record or a lot of records. It is a lot more efficient than trying to load that related data yourself.
In the view, you can output the driver info like this:
echo CHtml::encode($order->Driver->Name);
Unless you have a foreign key to ensure data integrity, it is possible that the Driver has been deleted without clearing his existing orders... In that case $order->Driver will be NULL and the line above will cause an error. Figuring out how to avoid it should be obvious.
In TaxiOrders admin use this to display driver name
TaxiDrivers::getName($data->driver_id);
Now in the TaxiDrivers Model write a function with sql query to get the driver name like this...
public function getName($getid) {
$sql = "SELECT name from `taxi_drivers` where `driver_id`='$getid'";
$command=yii::app()->db->createCommand($sql);
$rs = $command->queryScalar();
return $rs;
}
I Hope it will help you..
I always prefer Query Builder approach instead of Active record approach in joined scenarios. Like that
First Get Data through Query Builder
public function getTaxtOrder($id) {
$select = Yii::app()->db->createCommand()
->select('to.*, td.name as driver_name')
->from('TaxiOrders to')
->join('TaxiDriver td', 'td.id = to.driver_id')
->where('to.id = :id', array(':id' => $id));
return $select->queryRow();
}
Then Pass through controller
$data = TaxiOrders::model()->getTaxtOrder($id);
$this->render('view',array(
'data' => $data
));
Last use this into views
$this->widget('zii.widgets.CDetailView', array(
'data'=>$data,
'attributes'=>array(
array('label' => 'Order No', 'value' =>$model['order_no']),
array('label' => 'Driver Name', 'value' =>$model['driver_name']),
array('label' => 'Date', 'value' =>$model['order_date']),
),
));
This approach easily and flexibly work with multiple joined tables than Active Record Approach.

unable to fetch records from multiple tables using join

I am using Yii framework. i am wonder how i can get records from multiple tables i did research but couldn't find any usefull link i am using following code for this please let me know where i am missing
my model Task.php
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'prj_user' => array(self::BELONGS_TO, 'User', 'id'),
);
}
model User.php
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
array('task', self::HAS_MANY, 'Task','project_id')
);
}
and this is my main controller
$criteria = new CDbCriteria;
$criteria->compare('t.id', 1);
$criteria->with = array( 'prj_user' => array('select' => 'username,title,roles', 'joinType'=>'inner join'));
$rows = Task::model()->findAll( $criteria );
but still i am getting columns only from task table but i need more three columns from users table please help me
Let Yii worry about joining your tables. Your relations looks fine so you should be able to access them directly
For example, what does this return?
foreach ($rows as $task)
{
if ( isset($task->prj_user) )
echo $task->prj_user->username . "<br>";
}
Or this?
this->widget('zii.widgets.grid.CGridView', array(
'dataProvider'=>new CActiveDataProvider('Task'),
'columns'=>array(
'id',
'prj_user.username',
'prj_user.title',
'prj_user.roles',
)
));
->with() is used for eager loading, so at this point you probably don't need it. In fact, unless I misread you completely, you can remove your criteria all together.

YII dropdown menu, 2 models

I am new in PHP and yii framework so I need some help with the dropdown menu. In my database I have 2 tables - Category - id, name and News - id, title, content, category_id. How could I make the relation between these two controllers? When I post news I must choose the category from drop down menu. I'm sorry for the stupid question but I can't do it at this moment.
Simply place this in your News model:
/**
* #return array relational rules.
*/
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'category' => array(self::BELONGS_TO, 'Category', 'category_id'),
);
}
and this in your Category model:
/**
* #return array relational rules.
*/
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'newsItems' => array(self::HAS_MANY, 'News', 'category_id'),
);
}
whenever you have an instance of your Category, you can refer to your multiple news items like so:
$category = Category::model()->findByPk(1);
$category->newsItems; //an array of News objects
and you can refer back to the category like so:
$news = News::model()->findByPk(1);
$category = $news->category; //a Category object
I think your asking about how to show all the categories for selection when your creating a news item. In your form for creating the news object you need something like:
$cats = Category::model()->findAll();
$cats = CHtml::listData($cats, 'id', 'name');
$form->dropDownList($model, 'category', $cats);
For the relation between them and accessing it afterwards see Benjamin Bytheway's answer
You can do what paystey wrote all in one line like this:
<?php echo $form->dropDownList($model,'Category', CHtml::listData($CategoryModel::model()->findAll(array('order'=>'Text ASC')), 'CategoryID', 'Text'), array('empty'=> ' -- Select A Category -- '));?>
The last parameter of the list data is just what should display when the page loads.

Categories