I have 2 tables user and user_comment where user has many user_comments, i laid down the mapping being
User
$_dependentTables = array('User_Comments);
and
User_Comments
$_referenceMap = array(
'User' => array(
'columns' => 'id',
'refTableClass' => 'User',
'refColumns' => 'id'
)
);
Is there a way for me to do user->fetchAll() and get the user_comments without doing loop query (in cakephp it will do one query on user_comments where in (ids) then format it back to an array but i cant use cake). Is this possible in zend with me doing it manually? Thanks
Try this one
$sql=$this->getAdapter()->select()
->from("user_comment")
->join("user", "user.id=user_comment.userid")
->where("user_comment.id=?",$userId);
$result=$this->getAdapter()->query($sql)->fetchAll();
This might help u....
Related
I am using ICHIKAWAY's mongodb driver for cakephp.
One thing that I don't really get is how to perform a "LIKE" statement in cakephp using MONGODB.
I tried this statement:
$users = $this->User->find('all', array('conditions' => array('data_type' => 'user', 'profile.firstname LIKE' => '%'.$string)));
but its not working since "LIKE" is an mysql function.
Thanks for the suggestions.
Use MongoRegex
Mongo DB has a LIKE operator - it's simply a regular expression, to use it:
$users = $this->User->find('all', array(
'conditions' => array(
'data_type' => 'user',
'profile.firstname' => new MongoRegex("/$string/i")
)
));
There's an SQL Compatibilty behavior
The Mongodb driver contains a behavior providing sql syntax compatibility. To use it, simply make sure your model is using this behavior:
class User extends AppModel {
$actsAs = array(
'MongoDB.SqlCompatible'
)
}
And then you can use your query exactly as it appears in the question:
$users = $this->User->find('all', array(
'conditions' => array(
'data_type' => 'user',
'profile.firstname LIKE' => '%'.$string
)
));
I have a mysql table named users having fields: username, password, email
I have controller/action like this 'user/update' for adding new user and 'user/update/id/{user_id}'
I have same Zend_Form for both controller. For adding new user, I've checked whether the username already exist or not using below code:
$username->addValidator('Db_NoRecordExists', true, array('table' => 'user', 'field' => 'username'));
This works well when new user is added but when editing the user, even when the user leaves the username field as it is, i get username already exist error.
Is their a validation that zend provide similar to Db_NoRecordExists for editing the field.
In editing case,i want query like:
SELECT COUNT(*) FROM users WHERE username='$username' AND id!=$update_id
How can i do this?
You can convert your sql query into Zend_Db_Select
$select = Zend_Db_Table::getDefaultAdapter()->select()->from('users')->where('username =?',$username)
->where('id != ?',$update_id);
$validator = new Zend_Validate_Db_NoRecordExists($select);
Zend_Validate_Db_NoRecordExists has an exclude option for this case:
$validator = new Zend_Validate_Db_NoRecordExists(
array(
'table' => 'users',
'field' => 'username',
'exclude' => array(
'field' => 'id',
'value' => $user_id
)
)
);
I have a many to many relationship in FuelPHP as seen below:
protected static $_many_many = array(
'members' => array(
'key_from' => 'team_id',
'key_through_from' => 'team_id',
'table_through' => 'user_has_team',
'key_through_to' => 'user_id',
'model_to' => 'Model_User',
'key_to' => 'id',
)
);
But I wanted to know if you can have a where clause in the relationship. For example:
protected static $_many_many = array(
'members' => array(
'key_from' => 'team_id',
'key_through_from' => 'team_id',
'table_through' => 'user_has_team',
'key_through_to' => 'user_id',
'model_to' => 'Model_User',
'key_to' => 'id',
'where' => array('account_status' => 'active')
)
);
So it only returns Model_User objects which have their account_status set to 'active'. I know this is pushing it a bit but Fuel is awesome in lots of other was so I though there might be a way to do this.
Obviously you could do this with a query but I wanted to know if there is a way to do it using $_many_many
public function action_your_function_where_you_call_the_user_model()
{
$user = Model_User::find()->where('account_status', 'active')->get();
}
Bit late to the party, but for people hitting this one on a search:
You can define conditions on a relationship definition. At the moment 'where' and 'order_by' clauses are supported.
This conditions are permanent, you can't switch them on or off. So if you need both full and filtered access to a related model, you will have to define two relations.
See http://fuelphp.com/docs/packages/orm/relations/intro.html#usage_rel_conditions for more information.
I usualy use Zend_Validate_Db_RecordExists to update or insert a record. This works fine with one field to check against. How to do it if you have two fields to check?
$validator = new Zend_Validate_Db_RecordExists(
array(
'table' => $this->_name,
'field' => 'id_sector,day_of_week'
)
);
if ($validator->isValid($fields_values['id_sector'],$fields_values['day_of_week'])){
//true
}
I tried it with an array and comma separated list, nothing works... Any help is welcome.
Regards
Andrea
To do this you would have to extend the Zend_Validate_Db_RecordExists class.
It doesn't currently know how to check for the existence of more than one field.
You could just use two different validator instances to check the two fields separately. This is the only work around that I can see right now besides extending it.
If you choose to extend it then you'll have to find some way of passing in all the fields to the constructor ( array seems like a good choice ), and then you'll have to dig into the method that creates the sql query. In this method you'll have to loop over the array of fields that were passed in to the constructor.
You should look into using the exclude parameter. Something like this should do what you want:
$validator = new Zend_Validate_Db_RecordExists(
array(
'table' => $this->_name,
'field' => 'id_sector',
'exclude' => array(
'field' => 'day_of_week',
'value' => $fields_values['day_of_week']
)
);
The exclude field will effectively add to the automatically generated WHERE part to create something equivalent to this:
WHERE `id_sector` = $fields_values['id_sector'] AND `day_of_week` = $fields_values['day_of_week']
Its kind of a hack in that we're using it for the opposite of what it was intended, but its working for me similar to this (I'm using it with Db_NoRecordExists).
Source: Zend_Validate_Db_NoRecordExists example
Sorry for the late reply.
The best option that worked for me is this:
// create an instance of the Zend_Validate_Db_RecordExists class
// pass in the database table name and the first field (as usual)...
$validator = new Zend_Validate_Db_RecordExists(array(
'table' => 'tablename',
'field' => 'first_field'
));
// reset the where clause used by Zend_Validate_Db_RecordExists
$validator->getSelect()->reset('where');
// set again the first field and the second field.
// :value is a named parameter that will be substituted
// by the value passed to the isValid method
$validator->getSelect()->where('first_field = ?', $first_field);
$validator->getSelect()->where('second_field = :value', $second_field);
// add your new record exist based on 2 fields validator to your element.
$element = new Zend_Form_Element_Text('element');
$element->addValidator($validator);
// add the validated element to the form.
$form->addElement($element);
I hope that will help someone :)
Although, I would strongly recommend a neater solution which would be to extend the Zend_Validate_Db_RecordExists class with the above code.
Enjoy!!
Rosario
$dbAdapter = Zend_Db_Table::getDefaultAdapter();
'validators' => array('EmailAddress', $obj= new Zend_Validate_Db_NoRecordExists(array('adapter'=>$dbAdapter,
'field'=>'email',
'table'=>'user',
'exclude'=>array('field'=>'email','value'=>$this->_options['email'], 'field'=>'is_deleted', 'value'=>'1')
))),
For those using Zend 2, If you want to check if user with given id and email exists in table users, It is possible this way.
First, you create the select object that will be use as parameter for the Zend\Validator\Db\RecordExists object
$select = new Zend\Db\Sql\Select();
$select->from('users')
->where->equalTo('id', $user_id)
->where->equalTo('email', $email);
Now, create RecordExists object and check the existence this way
$validator = new Zend\Validator\Db\RecordExists($select);
$validator->setAdapter($dbAdapter);
if ($validator->isValid($username)) {
echo 'This user is valid';
} else {
//get and display errors
$messages = $validator->getMessages();
foreach ($messages as $message) {
echo "$message\n";
}
}
This sample is from ZF2 official doc
You can use the 'exclude' in this parameter pass the second clause that you want to filter through.
$clause = 'table.field2 = value';
$validator = new Zend_Validate_Db_RecordExists(
array(
'table' => 'table',
'field' => 'field1',
'exclude' => $clause
)
);
if ($validator->isValid('value') {
true;
}
I am using zend framework v.3 and validation via InputFilter(), it uses same validation rules as zend framework 2.
In my case I need to check, if location exists in db (by 'id' field) and has needed company's id ('company_id' field).
I implemented it in next way:
$clause = new Operator('company_id', Operator::OP_EQ, $companyId);
$inputFilter->add([
'name' => 'location_id',
'required' => false,
'filters' => [
['name' => 'StringTrim'],
['name' => 'ToInt'],
],
'validators' => [
[
'name' => 'Int',
],
[
'name' => 'dbRecordExists',
'options' => [
'adapter' => $dbAdapterCore,
'table' => 'locations',
'field' => 'id',
'exclude' => $clause,
'messages' => [
'noRecordFound' => "Location does not exist.",
],
]
],
],
]);
In this case validation will pass, only if 'locations' table has item with columns id == $value and company_id == $companyId, like next:
select * from location where id = ? AND company_id = ?
I'm using lithium with mongodb and I would like to know with my models below how I could get the data of the user from Posts::find('all'); query?
Do I have to do two queries?
Thanks for your help!
<?php
namespace app\models;
class Posts extends \lithium\data\Model {
protected $_schema = array(
'_id' => array('type' => 'id'),
'name' => array('type' => 'string', 'null' => false),
'description' => array('type' => 'string', 'null' => false),
'created' => array('type' => 'datetime'),
'updated' => array('type' => 'datetime'),
'user_id' => array('type' => 'integer')
);
protected $_meta = array(
'key' => '_id',
);
public $belongsTo = array('Users');
}
?>
<?php
namespace app\models;
class Users extends \lithium\data\Model {
public $hasMany = array('Posts');
public $validates = array(
'name' => 'Please enter a name',
);
protected $_schema = array(
'_id' => array('type' => 'id'),
'name' => array('type' => 'string', 'null' => false),
'slug' => array('type' => 'string', 'null' => false),
'created' => array('type' => 'datetime', 'null' => false),
);
}
?>
Currently relationships only exist for relational databases like MySQL and SQLite3. As such you'll need to make two queries to get the data you want. We're working on adding support for relationships for document based databases now however there currently is no timeframe on that.
You can use Set::extract on your result from posts to pull all of the user id's out then use the results from that to make a single query from users - so from posts you could do $userIDs = Set::extract('/posts/user_id', $posts->data()); then User::find('all', array('conditions' => array('_id' => $userIDs)));
hope this helps.
edit: You can find set::extract information here: http://li3.me/docs/lithium/util/Set::extract()
Do I have to do two queries?
This will depend on your schema.
Case #1
If Users and Posts are two different collections then you will need two different queries.
Case #2
If Users is the top level object and Posts "belongs to" Users then you would do something equivalent to db.users.find({ posts : {$exists:true} }).
I'm not 100% clear on how Lithium handles this. I cannot find a simple example of whether Lithium is doing #1 or #2.
As Howard3 said, there is currently no relationship support for MongoDB and as a result "belongs to" won't work either.
The actual decision depends on your application, but i assume that its going to be some form of a blog (users and posts). According to MongoDB schema design best practices, i'd put both in separate collections because they are "first level collections". a better fit for embedded documents would be posts and comments.
Also, you don't have to define the 'key' stuff when you're on latest master. You can write a custom find method for now that could be easily swapped to the more generic solution when relation support is finished in the core.
if you need more interactive help, visit #li3 on freenode.