How to get only one row from a table using cakephp - cakephp

I'm trying to retrieve data from one of the rows of a table using cakephp, and I want to get the values from the extracted row.
P.s. I've tried to follow cakephp's find(), but did not get anything, got an error instead.
Error`$login_id = $this->AppAuth->user('id');
$userSettings= $this->loadModel("UserSettings");
$userSetting= $this->$userSettings->find('first', array(
'conditions' => array('UserSettings.user_id' => $login_id)));`

From cakephp siteGot it.
$query = $internSettings->find('all', [
'conditions' => ['InternSettings.intern_id' => $login_id]
]);
$row = $query->first();
Now that I can retrieve a row, how am I suppose to access the values of the row?

$record = $internSettings->find('all', [ 'conditions' => ['InternSettings.intern_id' => $login_id]])->first();
This will returns Entity object in $record, you can access field by
echo $record->field_name;
or you can convert it in array and then you can access
$recordArr=$record->toArray();
echo $recordArr['field_name'];

Related

Why is CakePHP 3 paginator not sending options to custom finder method?

I'm trying to paginate with a custom finder in Cakephp 3.0.0-RC1. The docs say that I should do this:
$customFinderOptions = [
'tags' => $tags
];
$this->paginate = [
'finder' => [
'tagged' => $customFinderOptions
]
];
$articles = $this->paginate($this->Articles);
So my controller method contains
$this->paginate = [
'finder' => [
'recentActivity' => [
'limit' => 5,
'offset' => 2,
'foo' => 'bar'
]
]
];
$results = $this->paginate($this->ModelName);
At the top of ModelNameTable::findRecentActivity(), pr($options) results in this:
Array
(
[foo] => bar
[whitelist] => Array
(
[0] => limit
[1] => sort
[2] => page
[3] => direction
)
)
Where did limit and offset go? Digging in the CakePHP 3 core a bit, I see at the top of ORM.Table.php
public function callFinder($type, Query $query, array $options = [])
{
$query->applyOptions($options);
$options = $query->getOptions();
$finder = 'find' . $type;
if (method_exists($this, $finder)) {
return $this->{$finder}($query, $options);
}
Ah, so limit and offset went into $query. Unfortunately, I can't think of a practical way to get them back out from inside my custom finder method.
I checked, and $options accurately reflects the options I set before it's overwritten by $options = $query->getOptions(); and the limit and offset values are removed.
The docs led me to expect $options to be passed (in its entirety) to my custom finder method. So my question is...
Am I using the paginator component / customer finder incorrectly?
Is this intended behavior, or something I should report an issue about? I'm new to CakePHP 3 and still wrapping my head around it, so I didn't want to jump to the conclusion that it was a bug.
Sidenote: I know that I can hack around this by using different keys in $options, like foo_limit and foo_offset to accomplish what I want.
In understand where the confusion comes from. Apart from my concerns expressed in the question comments about the possibly contradictory options your query may get, I think you should know that the following list of options are directly copied to the query and not interpreted as custom options for your finder method:
'fields'
'conditions'
'join'
'order'
'limit'
'offset'
'group'
'having'
'contain'
'page'
Those options will call the matching query methods to set its internal state.
Turns out...
It is not true that all options set for the custom finder are ignored. Most options that are listed in José's answer are integrated into the query and then removed from $options before $options is passed to the custom finder method.
However, the custom finder's limit is always overwritten by either $this->paginate['limit'] or the default value of 20 (and likewise with page). But it looks like this has been identified as a bug and is going to be fixed.

Saving a model with no data in CakePHP (just create id in db)

My CakePHP Cart model/table has only one field: id.
It hasMany LineItems.
I am not having success saving the Cart model alone:
$this->Cart->create();
$this->Cart->save();
Or, by passing it a $data array structured as follows and using saveAssociated():
$data = array(
'Cart' => array(),
'LineItem' => array(
array(
'item_id' => $item_id,
'qty' => $qty,
'price_option_id' => $price_option_id
)
)
);
If I add a useless_field to the Cart table/model, and pass some data in it saves. So obviously the problem lies in my having a model with a table with just a single id field and not passing in any other data to save. It won't create what it must be assuming is an 'empty' record.
I have passed 'validate' => false into the saveAssociated call but it doesn't make a difference (and there are no validations for this model to ignore).
Is there a way to do this? Am I missing something? Please enlighten me!
CakePHP tables require created and modified fields, or for you to define your own fields (ie you can call them whatever you want but they do the same thing).
In this instance you would use
$this->Cart->set($data);
$this->Cart->saveAll();

CakePHP - Retrieving a list of options from another table, to use with form helper/ before Instering

Here is Yet another cakePHP question! I have table called blood_groups which has blood_group_id and group fields.. Then I have another table called donors, which has several fields such as name, surname etc. Another field included inside this table is the foreign key 'blood_group_id' which will need to map to the blood_group table on retrieval. in the donor registration view, i want to be able to retrieve the values from the blood_groups table, and display them using the formHelper (with their respective id's).
I have gone through CAKE doc, and I understand that I would need to create the association between my models, but I am struggling to figure this one out. Should I create $hasOne association inside the Donor Model (considering that the Donor table has the fk of the other table). And how would I go about retrieving the options of blood_groups from the blood_groups Model?
Should It work like this?(and are any other prerequisites involved?) :
In my DonorController -
$this->set('blood_groups', $this->Donor->Blood_Group->find('all'));
in Views/Donor/add.ctp
echo $this->Form->input('blood_group_id');
Accessing data through associations is fine. But for radios or checkboxes you want to do a find('list). Your model and variable name does not match the CakePHP convention, there should be no underscore.
Properly named this should be already enough to populate the input.
// controller
$this->set('bloodGroups', $this->Donor->BloodGroup->find('list'));
// view
echo $this->Form->input('blood_group_id');
If you don't follow the conventions for some reason:
echo $this->Form->input('blood_group_id', array(
'options' => $bloodGroups
));
See:
Linking Models Together
The Form Helper
Create one function in BloodGroup Model
function getDonors(){
$options = array(
// 'conditions' => array('Donor.blood_group_id'=>$id),
'joins' => array(
array(
'alias' => 'Donor',
'table' => 'donors',
'type' => 'LEFT',
'conditions' => array(
'Donor.blood_group_id = BloodGroup.blood_group_id',
),
)
),
'fields' => array('Donor.name','Donor.surname','Donor.blood_group_id',
'BloodGroup.blood_group_id')
);
$returnData = $this->find('all',$options);
return $returnData;
}
Now from controller call this function
App::import('model','BloodGroup');
$BloodGroup = new BloodGroup;
$donorList = $BloodGroup->getDonors();
$this->set('donorList',$donorList);
In view file you will get list of donors in $donorList.

Saving multiple records in cakephp using datasources

Is there a way to use saveAll() with a datasource in Cakephp 2.0? I've been able to successfully use save(), but saveAll() triggers an error.
Yes you can use the saveAll with the datasource. You should have to pass the array like:
$data = array([0] => array(
[ModelName] = array(
[fieldName] => value1,
...
)
)
[1] => array( ............
..............
)
Then if you use $this->ModelName->saveAll($data), you will be able to save multiple records at once. And also if you pass an option " 'deep' => true " then you will be able to save multiple records in multiple related tables.
$this->ModelName->saveAll($data, array('deep' => true));

CakePHP: find neighbors, order on 'name' or 'order'

I have a list of ordered items, ordered according to the int field order.
I'm creating a gallery in CakePHP 1.2 that has a prev and next button and those should link to the previous and next item according to their ordering, not according to their id.
In order to get this result I've included the 'order' parameter to the find function, and populated it with 'Item.order'=>'DESC'. Still the result is an id ordered list.
My question is: what do I do wrong?
My controller:
$this->Item->id = 16;
$neighbours = $this->Item->find('neighbors', array(
'order' => array('Item.order'=>'DESC'),
'fields' => array('id','name')
));
My Solution
I've tried a different approach. My code now does the job and looks as follows:
$order = $this->Item->findById(6);
$neighbours = $this->Item->find('neighbors', array(
'field' => 'order',
'value' => $order['Item']['order']
));
By setting the parameter 'field' to the field will be the ordering field, and set the 'value' parameter to the order value of you current Item you'll get the prev and next.
Yeah the problem was that you weren't including the order field in your fields array.
$neighbours = $this->Item->find('neighbors', array(
'order' => 'order DESC',
'fields' => array('id', 'name', 'order')
));
Unless you have related models with conflicting field names you don't need to include the Item. model prefix (though I usually do anyway to avoid such errors.) You're original syntax would work if you had included [Item.]order in "fields"
Finally, your solution is not optimal, you're making two SQL queries when you don't need to. and 'field' is not a query option as far as I'm aware which actually means you're returning all of the fields in the table.
I was having problems with this. Basically I have a list of questions that need to be randomly ordered (once only) per user session.
I was setting the order of the model to something like this:
'FIELD(TestQuestion.id, 3, 1, 5)';
This worked fine for normal queries, but finding neighbors is stymied by line 2897 in Model.php:
$query['order'] = $field . ' DESC';
So to get around it, I did the following:
Add a virtual field called 'examination_order', and set the order to that:
$this->TestQuestion->virtualFields['examination_order'] = 'FIELD(TestQuestion.id, 3, 1, 5)';
$this->TestQuestion->order = array(
$this->TestQuestion->alias . '.examination_order'
);
In the find neighbors call, set the 'field' to 'examination_order', with the value set to the index as found previously:
$neighbors = $this->TestQuestion->find(
'neighbors',
array(
'field' => 'examination_order',
'value' => $testQuestion[$this->TestQuestion->alias]['examination_order'],
'conditions' => $conditions
)
);

Resources