CakePHP Accessing Dynamically Created Tables? - mysql

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'

Related

Merging two JSON Objects in Node-Red

I am having some trouble trying to merge two JSON objects retrieved from my SQL Server database into a single object in Node-Red.
The flow I have created is the following:
For each call to the database I am receiving the following objects:
Plans:
[{"PlanID":2,"Status":0,"EndTime":"0001-01-01T00:00:00.000Z"}]
Goals:
[{"GoalID":1,"PlanID":2, "Type":2,"Message":"Walk 1000 km","Difficulty":0}]
I have created two functions which assign these objects into flow variables ('plans' and 'goals'), and now I was trying to merge both objects into a single JSON object.
I don't know if I have to use the Join node for this purpose and if so how to configure it, but my idea was to create a JSON object in this format:
[{"GoalID":1,"Plan":{"PlanID":2,"Status":0,"EndTime":"0001-01-01T00:00:00.000Z"}, "Type":2,"Message":"Walk 1000 km","Difficulty":0}]
First I wouldn't set them as flow variables as these will get over written if you get a second request in to the http-in node while the Database look ups are happening. Better to add them as msg variables then they flow with the msg and can't be overwritten.
Given you are not just combining the 2 objects to get the super set of keys and values you are probably best off just using either a function node or the change to assemble to the output object yourself.
Assuming the input looks something like:
msg.plans = [{"PlanID":2,"Status":0,"EndTime":"0001-01-01T00:00:00.000Z"}]
msg.goals = [{"GoalID":1,"PlanID":2, "Type":2,"Message":"Walk 1000 km","Difficulty":0}]
then the function node would look something like:
msg.payload = msg.goals[0];
msg.payload.plan = msg.plans[0];
delete msg.goals;
delete msg.plans;
return msg;
The change node rules would looks something like
The join node would work to get the 2 objects into an array or an object using the topics as keys to hold the 2 input messages.

How to query mongoDB using mongoose?

How do you query MongoDB using mongoose with node.js? I have it to where I can insert my JSON object to my DB, but all the ways I have tried to return the JSON object from the DB return null or just information about the database.
Is there some good method using mongoose to be able to query the database similar to the method:
var cursor = db.collection.find()
var JSONobject = cursor.next()
Here's what is in my code right now:
mongoose.connect('mongodb://localhost/myDB');
mongoose.connection.on('error', console.error.bind(console, 'connection error:'));
var cursor = mongoose.connection.db.contents.find();
console.log(cursor.next());
This throws an error at the line :
var cursor = mongoose....
claiming 'cannot call method 'find' of undefined'.
Note, that my collection 'contents' does in fact exist, and it contains one JSON document. I know this because I manually navigated to the collection using the mongo shell.
Edit: I am open to alternative methods to querying the database. I simply just want to be able to return JSON objects from my DB one at a time, while keeping track of where the client is at in the database.
One method to query mongoDB using mongoose is as follows:
Content.findOne().exec(function(err,docs){console.log(docs)});
Docs contains the JSON object. Access its attributes like any other object.
Note, this method uses asynchronous call backs. As such, you can't store the JSON object docs to a variable in order to use the JSON document information outside of the function. Therefore, you need to perform whatever actions needed with the JSON docs object information inside of the function.
For example, I was needing the query information to provide the filepath for my get api. As such, the result was as follows:
//get
app.get('/api/media/', function(req,res){
Content.findOne().exec(function(err,docs){res.sendFile(path.join(__dirname, '/api/media/', docs.filename))});
});
Note, Content is the model of my schema, and one of its parameters is filename.

How to insert json encoded inputs into foreign related tables

I am creating functionalities in yii+extjs. My client side is desighned in extjs and server side is in yii framework.
I am having two tables as
Poll Option
-pollId -optionId
-PollQuestion -option
-pollId
Now through poll creation form which will be in extjs,Question and its related option gets send to server in json format. So in yii framework,in actionCreate function will get input as-
$json='{"pollId":1,"PollQuestion":"Who is the best
cricketer","option":"ABC","option":"DEF","option":"XYZ"}'
$obj=json_decode($json);
During creation of poll,user can enter any number of options.So number of options can be anything.
i am creating above functionality in Pollcontroller.
So this newly created question gets inserted into Poll table as=
$model=new Poll();
$model->pollId=$obj->pollId;
$model->PollQuestion=$obj->PollQuestion;
Now i want to put all these new options in option table with same pollId. So how to add all these options in option table? Please help me
I would start by modifying the JSON so the options are a separate JSON within the pollquestion JSON.
Something like this...
$json='{"pollId": 1,"PollQuestion": "Who is the best cricketer",
"options":{[{"value":"ABC"},{"name": "DEF"},{"name": "XYZ"}]}';
That way when you decode it with json_decode you'll get an options array which you can go through and add each of the elements in that array in the options array.
for($i=0; $i<sizeof($obj['options']);$i++){
//Add to table logic here
}

Last inserted id in cakephp

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

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?