Last inserted id in cakephp - mysql

I use this code but its not working in cakephp and the code is:
$inserted = $this->get_live->query("INSERT INTO myaccounts (fname) values('test');
After this im using:
$lead_id = $this->get_live->query("SELECT LAST_INSERT_ID()");
It's working, but only one time.

Try this. Lots less typing. In your controller, saving data to your database is as simple as:
public function add() {
$data = "test";
$this->Myaccount->save($data);
// $this->set sends controller variables to the view
$this->set("last", $this->Myaccount->getLastInsertId());
}
You could loop through an array of data to save with foreach, returning the insertId after each, or you could use Cake's saveAll() method.
Myaccount is the Model object associated with your controller. Cake's naming convention requires a table called "myaccounts" to have a model class called "Myaccount" and a controller called "Myaccounts_Controller". The view files will live in /app/views/myaccounts/... and will be named after your controller methods. So, if you have a function add()... method in your controller, your view would be /app/Views/Myaccounts/add.ctp.
The save() method generates the INSERT statement. If the data you want to save is located in $this->data, you can skip passing an argument in; it will save $this->data by default. save() even automagically detects whether to generate an UPDATE or an INSERT statement based on the presence of an id in your data.
As a rule of thumb, if you're using raw sql queries at any point in Cake, you're probably doing it wrong. I've yet to run into a query so monstrously complex that Cake's ORM couldn't model it.
http://book.cakephp.org/2.0/en/models/saving-your-data.html
http://book.cakephp.org/2.0/en/models/additional-methods-and-properties.html?highlight=getlastinsertid
HTH :)

You can get last inserted record id by (works for cakePHP 1.3.x and cakePHP 2.x)
echo $this->ModelName->getLastInsertID();
Alternately, you can use:
echo $this->ModelName->getInsertID();
CakePHP 1.3.x found in cake/libs/model/model.php on line 2775
CakePHP 2.x found in lib/Cake/Model/Model.php on line 3167
Note: This function doesn't work if you run the insert query manually

pr($this->Model->save($data));
id => '1'
id is a last inserted value

Related

CakePHP virtual field: replace one string with another

I wonder if there is any way to declare a virtual field in CakePHP to do the following:
We have to replace a user's status with a symbol and append to it the user's nickname. For example, if a user is an admin, we want to display: #barth, for a regular user ~barth.
I already wrote an afterFind() callback to perform this task, but it fails using the containable behavior.
Either is there another way to implement it, or we can create a virtual field. The latter solution would be very elegant, but after googling I cannot find any way to use MySQL syntax to replace one string with another.
Ideas?
Virtual fields are very easy to use in Cake. You can use any regular MySQL function in their declaration to achieve this type of thing.
You'll first need to determine the SQL command to achieve what you want, I'd suggest using the CONCAT() function:
-- Return an # concatenated onto the username
CONCAT('#', yourfield)
Then add this as a virtual field in your model:
class YourModel extends AppModel {
public $virtualFields = array(
'yourVirtualField' => 'CONCAT("#", yourfield)'
);
}
Now, when you query this model you should be able to access it like this:
$example = $this->YourModel->find('first');
echo $example['YourModel']['yourVirtualField']; // #yourfield
Edit
Since your update, you've got the values you want to concatenate together in another model as virtual fields already. CakePHP doesn't allow you to use associated models' virtual fields when creating a new virtual field, but you can do a subselect query to manually get this data. Here's an SQL Fiddle example.

The method 'Skip' is only supported for sorted input in LINQ to Entities. The method 'OrderBy' must be called before the method 'Skip'

I am working on a Dynamic data.
after creating a dynamic model and registering in global.asax, like
DefaultModel.RegisterContext(typeof(masterEntities1),new ContextConfiguration() { ScaffoldAllTables = true });
when i run an application, it shows a list of tables but when i click any of the table it throws an exception:
The method 'Skip' is only supported for sorted input in LINQ to Entities. The method 'OrderBy' must be called before the method 'Skip'.
but i haven't declare any query into my application.
You must call .OrderBy' on your query if you use the .Skip method. For example if you were using something similar to the following:
results = results.Skip(pageNumber * size).Take(size);
In the case above you would have previously had to use the .OrderBy to order the query if you are planning on using paging methods or something of the like. If you have an Id field, adding this onto your original query expression should eliminate the error:
.OrderBy(x => x.Id);

Coldfuson CFScript "setSQL" method was not found

I've got a Coldfusion component, with a method in it called getColumnNames
This just queries a MySQL table, and returns the columnlist:
remote string function getColumnNames() {
qProcessCars = new Query();
qProcessCars.setDataSource('#APPLICATION.dsn#');
qProcessCars.setSQL('SELECT * FROM sand_cars WHERE 1 LIMIT 1');
qProcessCars = qProcessCars.Execute().getResult();
return qProcessCars.columnlist;
}
If I access this remotely in the browser, with page.cfc?method=getColumnNames, then I get the expected list of columns back.
However, if I try to access this from inside another method within the component, I get an error
remote string function otherFunction() {
...
sColumns = getColumnNames();
...
}
The error dump for the above code returns the message "The setSQL method was not found".
So can anyone help me find out why it works as a remote call, but not when called from another method inside the same component.
Problem may be caused some kind of race conditions. If you make few calls which interfere, at some point qProcessCars may already be query result, so invoking method is not possible.
I would try to make the qProcessCars variable local scoped (var qProcessCars = new Query();
) and/or try to use another variable name for query results.
Next possible step is to enclose the query building/executing code into named lock.
Ah I've answered my own question again. Sorry.
I've used the same name qProcessCars else where in the component, I hadn't put var in front of them.
I don't know WHY that was causing the problem, but it was. Maybe setSQL can only be called once per query object?

Does calling ToArray on IQueryable de-attach the entity in LinqToSql?

I have a LinqToSql query that returns an array of Article objects like so:
return db.Articles.ToArray();
I then loop over this array and start to delete some items that meet a certain criteria, for simplicity let's say I delete them all, like so:
foreach (var item in array)
db.articles.DeleteOnSubmit(item);
The call to DeleteOnSubmit(entity) throws an invalid operation exception, it's message says "Can not delete an entity that has not been attached". I modified the code to get the entity first then delete it and it worked just fine. Here's the working code:
db.DeleteOnSubmit(db.Articles.Where(c=>c.Id == item.Id))
Now, I know it would work if I modified the repository to return IQueryable instead of a native array, I just don't understand why? Does ToArray has anything to do with this invalid operation exception?
Thanks.
ps: db is a reference to a DataContext object.
I suspect your using different DataContexts when selecting entities and when submitting changes. If this is the case, the error is natural and would still happen if you returned an IQueryable instead of a native array. Either you Attach an entity to the new data context or you use the same where you selected the initial entities.
Can you put it all in one method and try?
The answer is "No", it doesn't.
Unless you are using differen't db for delete than select (could happenw ithout you realize it) or db.ObjectTrackingEnabled is set to false somewhere.

CakePHP Accessing Dynamically Created Tables?

As part of a web application users can upload files of data, which generates a new table in a dedicated MySQL database to store the data in. They can then manipulate this data in various ways.
The next version of this app is being written in CakePHP, and at the moment I can't figure out how to dynamically assign these tables at runtime.
I have the different database config's set up and can create the tables on data upload just fine, but once this is completed I cannot access the new table from the controller as part of the record CRUD actions for the data manipulate.
I hoped that it would be along the lines of
function controllerAction(){
$this->uses[] = 'newTable';
$data = $this->newTable->find('all');
//use data
}
But it returns the error
Undefined property:
ReportsController::$newTable
Fatal error: Call to a member function
find() on a non-object in
/app/controllers/reports_controller.php
on line 60
Can anyone help.
You need to call $this->loadModel('newTable') to initialize it properly. Cake needs to initialize $this->newTable properly, and call all the callbacks.
Of course, you don't need $this->uses[] = 'newTable';, that doesn't do anything except add another value to the $uses array.
try:
function controllerAction() {
$data = ClassRegistry::init('ModelNameForNewTable')->find('all');
}
If your table is called 'new_tables', your model name should be 'NewTable'