I'm using LIKE query but when specialist_id's order change it say no records found,
if specialist_id array have [1,2,3] in it then all the users with three specialties should be in results regardless of sequence, sequence array may have [3,2,1] or [2,1,3] but the users with these three specialties should be in results, here is my code with LIKE query:
$field = $this->User->find(
'all', array(
'conditions'=>array(
'User.specialist_id LIKE' =>'%'.$value.'%',
'User.role'=>'careproviderRole',
'User.gender'=>$this->request->data['gender'])
)
);
foreach ($field as $key => $value)
{
$field[$key]['Specialist'] = $user;
}
I have also tried with FIND_IN_SET:
$field = $this->User->find(
'all', array(
'conditions' => array(
'User.role' => 'careproviderRole',
'FIND_IN_SET(\''.$this->request->data['specialist_id'].'\', User.specialist_id)')
)
);
When you use LIKE with mask '%some%', it find all results with substring 'some'.
If you need to get some specific set of ids from table (1, 2 or 3), then use sql operator IN.
Example:
SELECT `specialist_id` FROM `User` WHERE `specialist_id` IN (1,2,3);
In your code it will be:
$field = $this->User->find(
'all', array(
'conditions'=>array(
'User.specialist_id' => $arrayOfSpecialistIds,
'User.role'=>'careproviderRole',
'User.gender'=>$this->request->data['gender'])
)
Related
I have a table called items and a table called item_pics.
item_pics has an item_id, file_name and a rank field (among others).
What I'm looking for is for each item my index page's $items array to contain the file_name from the item_pics matching the item's item_id with the lowest rank. So I can access like (or something like) this in my Items/index.ctp:
foreach ($items as $item):
$img = $item['Item']['ItemPic']['file_name'];
...
I'm pretty new to CakePHP, this is my first project. I thought that this within the Item model would cause item_pics data to be pulled (although I figured all related item_pics for each item would get pulled rather than just the one with the lowest rank):
public $hasMany = array(
'ItemPic' => array(
'className' => 'ItemPic',
'foreignKey' => 'item_id',
'dependent' => false
)
}
but I can see that no item_pics data is loaded (at the bottom of items/index):
SELECT `Item`.`id`, `Item`.`title`, `Item`.`description`, `Item`.`created`, `Item`.`modified`, `Item`.`type`, `Project`.`id`, `Project`.`item_id`, `Project`.`title`, `Project`.`description`, `Project`.`rank`, `Project`.`created`, `Project`.`modified`
FROM `laurensabc`.`items` AS `Item`
LEFT JOIN `laurensabc`.`projects`
AS `Project`
ON (`Project`.`item_id` = `Item`.`id`)
WHERE `Item`.`type` IN (1, 2)
LIMIT 20
also, while I would like projects to be joined in the view pages, I don't really need them in the index page.
I've done some searching and haven't been able to find exactly what I'm looking for. I suppose I could do a query within the index view item loop, but I'm trying to make sure I do things the right way... the CakePHP way. I assume I need to change something about my model relationships but I haven't had any luck.
CakePHP - Associations - HasMany, this makes it seem like I could order by rank and limit 1. But this didn't work... and even if it did, I wouldn't want that to affect the view pages but rather just the index page.
My Controller looks like this:
public function index($type = null) {
$this->Item->recursive = 0;
$conditions = array();
if ($type == "sale") {
$conditions = array(
"Item.type" => array(self::FOR_SALE, self::FOR_SALE_OR_RENT)
);
} else if ($type == "rent" ) {
$conditions = array(
"Item.type" => array(self::FOR_RENT, self::FOR_SALE_OR_RENT)
);
} else {
$conditions = array("Item.type !=" => self::HIDDEN);
}
$paginated = $this->Paginator->paginate($conditions);
debug($paginated);
$this->set('items', $paginated);
$this->set('title', ($type == null ? "Items for Sale or Rent" : "Items for " . ucwords($type)));
}
I have also tried this on my controller, but it doesn't seem to do anything either:
$this->paginate = array(
'conditions' => $conditions,
'joins' => array(
array(
'alias' => 'ItemPic',
'table' => 'item_pics',
'type' => 'left',
'conditions' => array('ItemPic.item_id' => 'Item.id'),
'order' => array('ItemPic.rank' => 'asc'),
'limit' => 1
)
)
);
$paginated = $this->paginate($this->Item);
First, set containable behavior in AppModel (or if you don't want it on each model, put it on Item model):
public $actsAs = array('Containable');
Then, on your find query:
$items = $this->Item->find('all', array(
'contain' => array(
'ItemPic' => array(
'fields' => array('file_name'),
'order' => 'rank',
'limit' => 1
)
)
));
Then the result array you can access it like:
foreach ($items as $item):
$img = $item['ItemPic']['file_name'];
Edit: Then you should put it on the paginate query:
$this->paginate = array(
'conditions' => $conditions,
'contain' => array(
'ItemPic' => array(
'fields' => array('file_name'),
'order' => 'rank',
'limit' => 1
)
)
);
In this case, I would probably order by rank and limit 1 as you said, and make that a dynamic association just for the index page (See http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html#creating-and-destroying-associations-on-the-fly). So use $this->Item->bindModel(array('hasMany' => array('ItemPic' => $options))); (which I believe should replace your current settings for HasMany ItemPic, but you may have to unbindmodel first)
Associations created through bindModel will go through for the next query only, then it'll revert to your normal settings, unless you specifically set an option to keep using the new association.
As for why it's not getting ItemPics with Items, or why trying to order by rank and limit 1 didn't work for you, I can't really say without seeing more of your code.
Learning php and I am losing my mind trying to solve this for days now. Please help.
This is a code which goes thought a table COUPON, take data with a condition met, and download it afterwards. In this table COUPON I have USER_ID as number but I want to have a user name also, which is kept in another table USER.
How can I go to another table (USER) and take names (REALNAME) by this USER_ID which is the same in both tables?
if ( $_POST ) {
$team_id = abs(intval($_POST['team_id']));
$consume = $_POST['consume'];
if (!$team_id || !$consume) die('-ERR ERR_NO_DATA');
$condition = array(
'team_id' => $team_id,
'consume' => $consume,
);
$coupons = DB::LimitQuery('coupon', array(
'condition' => $condition,
));
if (!$coupons) die('-ERR ERR_NO_DATA');
$team = Table::Fetch('team', $team_id);
$name = 'coupon_'.date('Ymd');
$kn = array(
'id' => 'ID',
'secret' => 'Password',
'date' => 'Valid',
'consume' => 'Status',
);
$consume = array(
'Y' => 'Used',
'N' => 'Unused',
);
$ecoupons = array();
foreach( $coupons AS $one ) {
$one['id'] = "#{$one['id']}";
$one['consume'] = $consume[$one['consume']];
$one['date'] = date('Y-m-d', $one['expire_time']);
$ecoupons[] = $one;
}
down_xls($ecoupons, $kn, $name);
After this, I want to try to do the same thing using only SQL queries.
You would need to JOIN the tables in the SQL query
SELECT something FROM coupons as coupons JOIN user as user ON coupons.id=user.id
You should use join when you want to retrieve details from two tables.
Join table COUPON and table USER based on user_id . This should yield results you want.
so I can look for concrete values by doing
$recordset= Model::find('all', array(
'conditions' => array(
'condition' => $somevalue
)
))
however, what do I do if I want to match on a partial value?
right now, I've resorted to writing the query myself, a la:
$abc = Connections::get('default')->
read('SELECT * FROM myTable WHERE condition LIKE "%partial string%"');
Here's how I do an SQL 'like' search:
$user = User::find('all', array(
'conditions' => array(
'first_name' => array('like' => '%yeun%'))
)
);
'like' being the keyword, there.
That would generate a query like:
SELECT * FROM `users` AS `Users` WHERE (`first_name` like '%yeun%');
Hope that helps.
The query below represents what I am trying to do, I need to pull in a list of blog_posts and also join with a users table.
What it is also doing is pulling in a random 'picture_filename' from blog_updates_pictures. It needs blog_updates as a join to reference the blog_update_id.
What I'd like to do now is also COUNT the number of blog_updates for each blog_post. I think this is a subquery but every implementation fails. It would also be good to have the count accept arguments (ie. blog_updates where date = ?). Also, there may be no updates or pictures to a blog_post.
$select = $db->select ();
$select->from ( array ('b' => 'blog_posts' ), array('headline', 'date_created'));
$select->join ( array ('u' => 'users' ), 'u.user_id = b.user_id', array ( 'email' ) );
$select->joinLeft ( array ('bu' => 'blog_updates' ), 'bu.blog_id = b.blog_id', array () );
$select->joinLeft ( array ('bup' => 'blog_updates_pictures' ), 'bu.blog_update_id = bup.blog_update_id', array ('picture_filename' ) );
Can someone show me the way?
Thanks
What I'd like to do now is also COUNT the number of blog_updates for each blog_post.
You can achieve that using aggregation - use GROUP BY bu.blog_id, and as additional column COUNT(bu.blog_id) AS blog_updates_count. It should work.
Create subselects as:
$subselect = $db->select()
->from(
array ('bu' => 'blog_updates' ),
array(
'blog_id',
'updates' => 'count(*)'
)
)
->group("bu.blog_id");
And then join the $subselect with your main $select as:
$select->join(
array( 't' => $subselect),
"t.blog_id = b.blog_id",
array( 'updates' )
);
If we had the table structure you might get a more complete answer
I want to be able to put 'or' condition inside a foreach loop when defining pagination variable at the controller like below:
foreach($p as $ps){
$this->paginate = array(
'or' => array(
array('Petition.commune_id LIKE' => $commune_ids['Commune']['id'] . ","),
),Recipe
'limit' => 10
);
}
I know above is wrong but I've compiled the codes for demonstration purposes. Is there a way we can do this in cake?
I need to loop because I want to be able to use ids from another table (which has been fetched as an array by find method) and use this for looping in the current table which is Petitions table. $commune_ids['Commune']['id'] is what I need to loop through as or value. Alternatively the query will be like:
SELECT * FROM petitions WHERE commune_id = 971 OR commune_id = 123 OR commune_id = 321 OR commune_id = 432
but of course I can do this in find function but I would like to paginate this results...
What you want is the query:
SELECT * FROM petitions WHERE commune_id IN (971, 123, ...)
In Cake, that's:
'conditions' => array(
'Petition.commune_id' => array(971, 123, ...)
)
So you make an array of ids which you can put into the condition. Done.
$communeIds = /* assemble array somehow */;
$this->paginate = array(
'conditions' => array(
'Petition.commune_id' => $communeIds
),
'limit' => 10
);