Relate to another table without using prefixes - php

So i have a task of creating a mobile version of an existing website but its built with a different framework which i didnt started.
The client wants to use CakePhp on it. so im using CakePhp 2.5.7. My question is. Is there a way to relate another table from an existing table without using prefixes?
To make it more clear i have this on my controller
public function index(){
$this->loadModel('Bulletin');
$bulletins = $this->Bulletin->find('all');
}
in my model
class Bulletin extends AppModel{
var $useTable = 'bulletin';
var $hasMany = array(
'BulletinComment' => array(
'className' => 'BulletinComment',
'foreignKey' => 'bulletinid',
),
);
}
but the bulletincomment table on the database has no prefix. and showing error on page
Error: Table bulletincomments for model bulletincomment was not found in datasource default.
I tried creating BulletinComment model like this
class BulletinComment extends AppModel{
var $useTable = 'bulletincomment';
}
but to no avail. Im still getting error. Is it possible to use any relation without adding prefixes?

Assuming prefixes are setup in the database connection (/app/Config/database.php) you can override it for one table if you add this to the model:
public $tablePrefix = '';
Or you could remove the prefix in the connection and add it back for the models that need it, depending on which is faster.

Related

Missing database table - CakePHP

I have a CakePHP project having 3 plugins: plugin1, plugin2, plugin3. These are simple plugins, I've just tried to split up my project into 3 smaller & easier parts.
Plugin1 has to use a model "Model1", where there is no db table for this table. And Cake is showing error :
"Missing Database Table
Error: Table models1 for model Model1 was not found in datasource default."
Here, table-name and Model-name are in correct convention. I don't want to create a table for this, since I don't need it. What to do now ?
You can set that model is without table by setting $useTable in the model (from CakeBook)
class Example extends AppModel {
public $useTable = false; // This model does not use a database table
}

Cakephp - Multiple Models for one Table

I have a User model that is used to store data on users of a dental examination system.
Typically, three types of users will exist: Admininistrator, Location Manager and Examiner.
It seems to have become necessary to treat these three roles as seperate models in my application (imagine how I'd have a different view for each role with different options etc... It's a nightmare).
How would I go about setting up the relationships in each Model.
My first thought is:
//Administrator Model
class Administrator extends User {
$name = 'Administrator';
$table = 'User';
$belongsTo = array(
'User' => array(
'className' => 'User',
'conditions' => array('User.role' => 'administrator'),
)
);
}
And then the User model will reference this one using a hasMany? In terms of CakePHP convention, how would one actually model this accurately?
Also, would this model extend the User model or the AppModel?
Of course you can create different models using the same table name. To do so, link each model with specific table with $useTable property (not $table):
class Administrator extends AppModel {
public $useTable = 'User';
}
But I don't know any CakePHP model property which will allow you to filter data returned when fetching results... You can only write your own conditions when linking model with another one, for example:
class SomeOtherModel extends AppModel {
public $hasMany = array(
'Administrator' => array(
'className' => 'Administrator',
'conditions' => array('Administrator.role' => 'administrator')
)
);
}
Which is not a good solution, because it will work only when executing queries for SomeOtherModel model.
You can also try applying an afterFind() callback to your Administrator / Examiner / ... models which will delete users of another role than needed, but of course it is not an efficient solution.
Another solution is just creating different database views which will contain only users of selected role (more on views - here). Then you can point each view to your CakePHP model, just as it was a normal database table.
But this solution is also not perfect. If you will have to add a new user role or change your table schema in the future, you will also have to modify your database views.

CakePHP: $this->paginate() and server hangs

So, I have this piece of code:
class ProductsController extends AppController {
var $name = 'Products';
var $paginate = array('limit' => 5); // sets the number of entries per page
function index() {
$this->Product->recursive = 0;
// works up to here fine
$this->set('products', $this->paginate()); // makes the browser hangs
}
}
When I go to ../products/index the browser just kind of hangs. It tries to load for minutes without giving any error messages, and I'm forced to restart Apache (XAMPP) or wait out a 60 seconds. The problem seems to be with $this->paginate() and all of the associations with Product controller. It has 2 belongsTo (belongs to smaller tables) and 1 hasOne (has one large table, 20K+ rows).
I added a hasOne relationship to the product model, and this seems to be causing the hanging. When I remove this relationship, the URL works and displays all items. However, this hasOne relationship does not cause any errors when I do for example, ../products/view/1.
Any idea on how to make this manageable?
There are a few things you can look at to start debugging. The first is your logs. Check both SQL and PHP logs for slow queries and timeout errors respectively.
If your Product model has a lot of associations, I suggest using ContainableBehavior. Actually, I suggest always setting $recurisve = -1; on the model and using Containable to fetch associations. It will speed up your app dramatically. Why pull data you don't use in your views?
In your app_model, add the behavior:
class AppModel extends Model {
var $recursive = -1;
var $actsAs = array('Containable');
}
Then modify your find queries to grab the associated data that you want:
$this->Product->find('all', array(
'contain' => array
'Category',
'Type'
)
));
Where Category and Type are associated with Product. This will tell Cake to just pull that associated data.
Then look at your queries. Use DebugKit to help you analyze timing and slow queries.
These are some basic methods for speeding up your finds. There's a ton of information out there for optimizing your CakePHP app, which is what sounds like may be the problem.

Cakephp and database with uncomon structure

how can I access any table from database in my model?
For example, I have Indexcontroller and code inside it:
$results = $this->Index->query("SELECT COUNT(*) FROM my_own_table");
Error: Database table indices for model Index was not found.
So, as I understand, I can access only table with naming related to model/controller name. But what to do if I can't modify the table naming and I want to access it's data?
You're not limited to using a model that's directly associated with your controller (this is just default behaviour); you can use any model.
To achieve what you want, create a new model for this table, eg. MyOwnTable, and in your controller, you can add this property to the class:
public $uses = array('Index', 'MyOwnTable');
Now you can access MyOwnTable using CakePHP's built in ActiveRecord functionality:
$results = $this->MyOwnTable->find('count');
If you have other tables you want to access, simply create models for those and add them to the $uses property. (You can also use $this->loadModel('Model') inside the action if you prefer).
If you have a table name that isn't very readable (eg. my_tb_own_1_x or some such), you can call the model class something human readable (eg. MyTable), and add the $useTable property to the model:
public $useTable = 'my_tb_own_1_x';
/* and change the default primary key if you have an unusual one */
public $primaryKey = 'my_tb_own_1_x_idx_pk';
See the CakePHP manual for more info on how to change default model and controller behaviour:
1.3 - Model Attributes
2.0 - Model Attributes
1.3 - Controller Attributes
2.0 - Controller Attributes
Nope. You can access different tables. However, CakePHP stumbles over the fact that the table that is associated by default to the Index model doesn't exist.
In other words, the model Index expects a table 'indices' to exist (and an error is thrown when it doesn't). You can do one of two things:
Create a table indices
Add the following to your Index model: var $useTable = false;
If you have any use for an indices table I'd go with option 1. If you're not going to use the indices table, go with option 2.
If you go with either step 1 or 2, your example should start working.

CakePHP: controller uses another model instead of its own

The situations looks like this: I have two models with controllers and everything, WrittenTest and WrittenTestAnswer. The problem is that whenever I try to access model WrittenTestAnswer, both from WrittenTestsController (using $this->loadModel() before) and from its own WrittenTestAnswersController, it somehow accesses WrittenTest instead. I noticed it when data wasn't saved to WrittenTestAnswer, $this->WrittenTestAnswer->find() also returned data from written_tests table. I have no idea what's going on. I checked names and stuff so many times already. I am using CakePHP 1.3. Thanks for any help.
EDIT:
code from WrittenTestAnswer model:
class WrittenTestAnswer extends AppModel {
public $name = 'WrittenTestAnswer';
public $displayField = 'written_test_answer';
public $belongsTo = array(
'WrittenTest' => array(
'className' => 'WrittenTest',
'foreignKey' => 'written_test_id',
),
);
}
EDIT so for example this (in WrittenTestAnswersController)
debug($this->WrittenTestAnswer->name);
outputs WrittenTest. And
$this->WrittenTestAnswer->find('first');
returns first row from written_tests. Any idea what's going on?
How are you accessing the model? If the relationships are setup correctly, you shouldn't need to use $this->loadModel() at all. You can just access the related model through its parent like so:
$this->WrittenTest->WrittenTestAnswer->find('all');
This might not be the cause of your problems but we cannot tell until you actually post the code that's not working.

Categories