Retrieving info from multiple tables using joins in sql with cakephp - mysql

My table structure is below
recipies
categories
ingredients(contain category_id)
recipies_categories
recipies_ingredients
Using cakephp I want to retrieve ingredients of a specified category of a specified recipe. For example I have-
recipies:recp1,recp2,recp3
categories:cat1,cat2,cat3
ingredeints:ing1,ing2,ing3
recipies_categories:recp1-cat1,recp2-cat2,recp2-cat3,recp3-cat3
ingredients_categories:ing1-cat1,ing2-cat2
Given recipe=recp2, category=cat1 or cat3 I should get no ingredients
Given recipe=recep2, category=cat2 I should get ing2
I have tried various ways using joins but couldn't get the result. Anybody can help?

$settings = array();
$settings['recursive'] = 1;
if (!empty($selected_categories)) {
$this->Ingredient->Behaviors->load('Containable');
$settings['conditions'] = array(
'Ingredient.category_id' => $selected_categories //array containing selected catagory ids
);
$settings['contain'] = array(
'Category' => array('id', 'name')
);
}
$settings['joins'] = array(
array('table' => 'recipes_ingredients',
'alias' => 'RecipesIngredient',
'type' => 'INNER',
'conditions' => array(
'RecipesIngredient.ingredient_id = Ingredient.id',
'RecipesIngredient.recipe_id' => $recipe_id //selected recipe
)
)
);
$this->Paginator->settings = $settings;
$ingredients = $this->Paginator->paginate($this->Ingredient);

Related

cakephp virtual fields with subquery and if

I have a Category table with a name field.
I want to be able to overwrite that name using a PartnerCategory Table and join it.
So usually I would get the Category like this:
$options = array(
'contain' => array('PartnerCategory'),
'conditions' => array(
'Category.slug' => $slug,
'Category.status' => true,
)
);
$category = $this->Category->find('first', $options);
And then check, if ParentCategory.name is not empty and replace the Category.name with it.
Overwriting the name with php is tedious so I checked virtual fields.
I can overwrite the Category.name using this:
$this->virtualFields = array(
'name' => 'SELECT name FROM app_partner_categories WHERE category_id = 1 AND partner_id = 60'
);
But if the name in the PartnerCategory table is empty or no mathes are found, the Category.name would be null.
How can I overwrite Category.name only if PartnerCategory.name is found?
Not sure but this could be a possible solution:
$joins = array(array('table' => 'app_partner_categories',
'alias' => 'PartnerCategory',
'type' => 'INNER',
'conditions' => array(
'PartnerCategory.category_id = Category.id'
)
)
);
$options = array(
'fields' => array('IF(PartnerCategory.name IS NULL or PartnerCategory.name = "", Category.name, PartnerCategory.name) as overwritten_name'),
'joins' => $joins,
'conditions' => array(
'Category.slug' => $slug,
'Category.status' => true,
)
);
$category = $this->Category->find('first', $options);

How to use conditions in self association without joins?

I have Product model [id, parent_id, x].
I want to append on each Product, single ProductParent, only when Product.x = 0, and Product.parent_id = ProductParent.id.
What i try is:
public $hasOne = array(
'ProductParent' => array(
'className' => 'Product',
'foreignKey' => false,
'conditions' => array(
'ProductParent.id = Product.parent_id',
'Product.x' => 0
)
)
);
And get output Product.parent_id is unknown.
You can try using Tree behavior. Check this: http://book.cakephp.org/2.0/en/core-libraries/behaviors/tree.html

how use multiple conditions to get data from 2 HABTM tables in Cakephp 2.x

I'm trying to get only those products which have specific brand and category.
in Product model i used this query
$products = $this->find('all', array(
'joins' => array(
array('table' => 'brands_products',
'alias' => 'BrandsProducts',
'type' => 'INNER',
'conditions' => array(
'BrandsProducts.brand_id' => $brandId,
'BrandsProducts.product_id = Product.id'
)
)
),
'group' => 'Product.id'
));
By using above query i can get only those products which has specific brand id.
Exactly i don't know how to use multiple conditions to get data from 2 HABTM tables.
in my example product HABTM relation with Category and Brands.
$products = $this->find('all', array(
'joins' => array(
array('table' => 'brands_products',
'alias' => 'BrandsProducts',
'type' => 'INNER',
'conditions' => array(
'BrandsProducts.brand_id' => $brandId,
'BrandsProducts.product_id = Product.id'
)
),
array('table' => 'categories_products',
'alias' => 'CategoriesProducts',
'type' => 'INNER',
'conditions' => array(
'CategoriesProducts.category_id' => $categoriesId,
'CategoriesProducts.product_id = Product.id'
)
)
),
'group' => 'Product.id'
));
By using this query i got error in db. SO i'm looking how to write proper query to get only those products where brand and category match.

Convert the MySql query to CakePhp 2.0

How do I convert this MySql query to CakePhp's find.
And please tell me how can i practice writing Find queries in cakephp
select distinct trips.fk_userid from spots, trips
where spots.fk_tripid = trips.id
and trips.isapproved = 1
and spots.id in (".$row[$first_index]['spot_list'].")
The model can be Trip and you can query like this
$this->Trip->query("select distinct trips.fk_userid from spots, trips where spots.fk_tripid = trips.id and trips.isapproved = 1 and spots.id in (".$row[$first_index]['spot_list'].")");
or
You should create Trip and Spot model and in Trip model, you have to have this in Spot model:
public $belongsTo = array(
'Trip' => array(
'className' => 'Trip',
'foreignKey' => 'fk_tripid'
)
);
and query it like this:
$this->Spot->find('all', array(
'fields' => array("distinct Trip.fk_userid"),
'conditions' => array(
'Trip.isapproved' => 1,
'Spot.id' => $row[$first_index]['spot_list']
)
));

Association of models(JOIN) not working in cakephp, shows empty results

I am purely new to cakephp and currently working on a project that is built in version 1.3. Basically I am trying to display the city names of the providers which are inserted in the database.
I have two models : gal_store.php and gal_location.php. In the gal_store model, the stores names are saved with their corresponding city ids in city field in gal_stores table. The table gal_locations contains all the cities and their names.
So I tried to JOIN the two tables as below :
var $hasOne = array(
'GalLocation' => array(
'className' => 'GalLocation',
'foreignKey' => 'id',
'conditions' => '',
'fields' => '',
'order' => ''
),
);
function getList($limit = 50,$whether_list = false){
$recursive = -1;
$conditions = array("GalStore.city"=> "GalLocation.id");
//$conditions = "";
$order = array("GalStore.address");
if($whether_list == true){
return $this->find("list",array("DISTINCT GalStore.city","recursive"=>$recursive,"limit"=>$limit,"order"=>$order,"conditions" => $conditions));
}else{
return $this->find("all",array("DISTINCT GalStore.city","recursive"=>$recursive,"limit"=>$limit,"order"=>$order,"conditions" => $conditions));
}
}
But in the ctp file when I do a var_dump($gal_locations); it always shows empty ! What is the reason ?
If the gal_locations has one to one relationship with gal_stores, use below code:
var $hasOne = array(
'GalLocation' => array(
'className' => 'GalLocation',
'foreignKey' => 'city',//if the city field contains the id of gal_locations table
'conditions' => '',
'fields' => '',
'order' => ''
),
);
If the gal_locations has one to many relationship with gal_stores, use below code:
var $belongsTo = array(
'GalLocation' => array(
'className' => 'GalLocation',
'foreignKey' => 'city',//if the city field contains the id of gal_locations table
'conditions' => '',
'fields' => '',
'order' => ''
),
);