I'm having difficulty in creating a Cake 2.0 plugin with a model that is not associated with an underlying database table.
The Cake Manual says that you can set the variable public $useTable = false; but when I load my plugin with this in my model I still get the missing database table error message.
This is the beginning of my class definition (where my plugin is called OneTime):
class Ticket extends OneTimeAppModel {
/*
* This model does not use a database table
*
* #var boolean
*/
public $useTable = FALSE;
What am I doing wrong here?
For a workaround in the meanwhile, I've been using this:
public $uses = array();
Related
Is it possible to read tables from another database using the builting CakePHP model features? I don't mean having an entirely different configuration in DATABASE_CONFIG but using the same host, user and password. The obvious thing:
class Provincia extends AppModel {
public $useTable = 'shared_data.dbo.provincia';
}
class DebugController extends AppController {
public function index() {
/* #var $modeloProvincia Provincia */
$modeloProvincia = ClassRegistry::init('Provincia');
$provincias = $modeloProvincia->find('all');
}
}
... triggers:
Error: Table shared_data.dbo.provincia for model Provincia was not found in datasource default.
I'll share my findings so far...
Short answer: you cannot.
CakePHP magic depends heavily on information about tables and columns fetched from the INFORMATION_SCHEMA views. That information is gathered in \Sqlserver::listSources (list of tables) and \Sqlserver::describe (list of columns).
While it's possible to extend the datasource driver and reimplement these methods:
// Model/Datasource/CustomSqlserver.php
class CustomSqlserver extends Sqlserver {
}
class DATABASE_CONFIG {
public $default = array(
'datasource' => 'CustomSqlserver',
// ...
);
}
... that's just the tip of the iceberg. The data structures account for two levels:
Schema (e.g. dbo)
Table (e.g. users)
They aren't designed for an extra database level on top. As a result, you end up needing to patch so much code that it isn't worth the effort.
I've also been playing with Synonyms in SQL Server. It's a more promising path because, while you still need to write \CustomSqlserver::listSources and \CustomSqlserver::describe yourself, to most (not all) effects they behave like regular tables. The main restriction though is that there can't be duplicate table names.
You would need to add a new connection to DATABASE_CONFIG, but you could do this in the constructor so that you can inherit your default database credentials and just modify the database name:-
public function __construct() {
$this->alt = $this->default;
$this->alt['database'] = 'provincia';
}
Then in your Provincia model you can swap to the alt database connection:-
public function __construct($id = false, $table = null, $ds = null) {
parent::__construct($id, $table, $ds);
$this->useDbConfig = 'alt';
}
I'm trying to create a temporary table within CakePHP 2.x, but I always receive the message "Error: Call to a member function query() on a non-object".
I did some research and found a solution, but this one is not working for me: Create temporary table in CakePHP and load it as a Model
EDIT:
The following code now produces a different error: "Error: Table devices_cls for model DevicesCl was not found in datasource default."
Here is my code:
class DevicesController extends AppController {
public $uses = array('Device','Client');
public function index(){
$conditions = array();
$tmpModel = 'DevicesCl';
$tmpTable = 'devices_cls';
$this->loadModel('DevicesCl');
$this->DevicesCl->query("CREATE TEMPORARY TABLE IF NOT EXISTS devices_cls AS (SELECT uuid,ownerUuid,status,os,imei,updatedOn,msisdn,model FROM device)" );
As I'm quite new to CakePHP, do I need to add an additional model class? I don't think so, as this should be handled by the temporary table - right?
Thanks for your support!
class DevicesController extends AppController {
public $uses = array('Device','Client');
public function index(){
$conditions = array();
$tmpModel = 'DevicesCl';
$tmpTable = 'devices_cls';
$this->loadModel('DevicesCl');
$this->DevicesCl->useTable=false;
$this->DevicesCl->query("CREATE TEMPORARY TABLE IF NOT EXISTS devices_cls AS (SELECT uuid,ownerUuid,status,os,imei,updatedOn,msisdn,model FROM device)" );
$this->DevicesCl->useTable = $tmpTable;
The problem is that the Model "DevicesCl" does not exist yet.
in your example on the link : the Model exist
so if you change
$this->DevicesCl->query(...)
to
$this->Model->query(...)
But i don t see why you need a functionnality like that... i think there are surely best solutions no ?
In Cakephp 3, you can do the following:
Model/Table/MyTempTable.php
<?php
// ......
class MyTempTable extends Table{
public function initDownload(){
$connection = ConnectionManager::get('default');
$connection->execute('CREATE TEMPORARY TABLE temptemp as (select * from refernece_db)');
// Do your thing
}
}
// When use the temp table, first should do:
$this->MyTempTable->initDownload();
// Then, can use Cakephp3 Table syntax normally as if it is a normal table
I'm writing an installation script for my CakePHP web application. I have a InstallController with 6 actions: step1, step2, step3, etc.
At step1 I'm handling Config/database.php creation. Because this file is empty and no datasource is available I have to set public $uses = false; in the InstallController.
At step2 the Config/database.php file is set so I should be able to make a connection to the datasource. This is also necessary because I want to update some database fields in the following steps.
Is it possible to update the public $uses = false; in every following steps after step1?
I'm using CakePHP version 2.3.5
Have you considered loading the model within the actions? So, something like:
<?php
App::uses('AppController', 'Controller');
class InstallController extends AppController {
public $uses = false;
public function step1() {
}
public function step2() {
$this->loadModel("Install");
$this->Install->callMethod();
}
}
In CakePHP 2.x models are lazy loaded, so as long as your step1 action doesn't try to make use of a model, you can safely declare the models in your controllers $uses property, they are not being constructed until your code actually makes use of them.
However, if for some reason you'd actually need to modify $uses, well then just do it, as mentioned models are lazy loaded, so you can modify $uses whenever you want and then access the models afterwards via magic properties on the controller.
I am building a new app based on multiple databases with many tables which don't follow any Cake conventions. I want to use CakePHP but I'm not sure if it's possible without the database in a Cake format.
Problems include:
Tables not named as Cake expects
Primary keys are not necessarily named id (e.g. it might be order_id)
Foreign keys are not necessarily named like other_table_id
Changing the database tables is not an option.
Is it possible to manually configure the schema in each model so that Cake will then know how the model relationships need to work? Or should I just give up on using Cake?
yes. you can still use CakePHP in your case.
Check out various Model attributes to fit your needs
http://book.cakephp.org/2.0/en/models/model-attributes.html.
e.g.
public $useTable = 'exmp' can be used to configure what table to use.
public $primaryKey = 'example_id'; can be used to configure the primary key's name
**Try this code sample............**
More detail here http://book.cakephp.org/2.0/en/models/model-attributes.html
<?php
class Example extends AppModel {
// Name of the model. If you do not specify it in your model file it will be set to the class name by constructor.
public $name = 'Example';
// table name example
public $useTable = example;
// example_id is the field name in the database
public $primaryKey = 'example_id';
}
?>
I am new to ASP.Net MVC . Any help is greatly appreciated in resolving my problem.
I am using a LINQToSQL db in my MVC application. For one of the auto generated partial class (Example MyClass assume for table MyClass) , I created another Partial class as MyClass and added DataAnnotations Like following...
namespcae NP
{
[MetadaType(typeof(myData))]
[Serializable()]
public partial class MyClass
{
}
public myData
{
[Required]
public string ID { get ; set ;}
// Other properties are listed here
}
}
In my controller class example MyHomeController
I have a code as follows:
List<MyClass> list = new List<MyClass>();
list = dbContext.StoredProcedure(null).ToList<MyClass>()
session["data"] = list.
above code works fine if I use inProc session state. But if I use SQLServer mode then I get error as
"Unable to serialize the session state. In 'StateServer' and
'SQLServer' mode, ASP.NET will serialize the session state objects,
and as a result non-serializable objects or MarshalByRef objects are
not permitted. The same restriction applies if similar serialization
is done by the custom session state store in 'Custom' mode. "
Can anyone tell me what I am doing wrong here..?. I can see the data is getting populated in ASPState database tables. By application throws error as follows.
Just mark as Serializable all classes whose instances you want to store in Session.
Finally I was able to resolve the issue.
Solution:
Add the below statement before querying the database. In my case I was calling LinqToSQl context( dbContext).
dbContext.ObjectTrackingEnabled = false;
Sample Code:
List empList = new List();
dbContext.ObjectTrackingEnabled = false;
empList = dbContext.SomeStoredProcedure().ToList()
Session["employee"] = empList.