cakephp association error? - cakephp

Warning (512): Model "User" is not associated with model "User" [CORE\cake\libs\model\behaviors\containable.php, line 340]
im getting this error when accessing datas of photo, friend
user has many photos and friend, photos and friend belongs to user
in photos index page, two warnings one for user mentioned above and other for 'Friend' as same friend is not associated with model 'friend'
what to do? what to check?

You have some mismatch with assotiations.
You can have situation similar to this:
User habtm array("Friend"=> array("className"=>"User")
And when finding users:
$this->User->find("all", array(
"contain"=>array("User");
));
instead of:
$this->User->find("all", array(
"contain"=>array("Friend");
));
Check this or post some code :)

Related

CakePHP relations in Database

I baked two controllers users and moves. Now I want to link the moves the users is linked to (only one). The bake did most of the work for me (thank god).
<td><?= $user->has('move') ? $this->Html->link($user->move->name, ['controller' => 'Moves', 'action' => 'view', $user->move->id]) : '' ?></td>
It actually show nothing. I have a foreign key in my database and the move 1 is correctly linked to the user.
foreign key in users "move_id" - primary key in the moves is "id"
I get no error and also no debug call. Any ideas?
It's showing nothing because in your ternary operator, it's executing this next portion >>>>>>>
: ''
and therefore prints a blank. Your $user object probably doesn't have a field called "move".
You need to check the following:
Are associations defined for these two models?
In your controller, where you're fetching this $user before doing $this->set(.....), did you mention "contain"? Since you need to access the Users as well as the Moves models?
For example:
// If you're trying to find all users records
$users = $this->Users->find('all')
->contain(['Moves']);
// For a single user record
$users = $this->Users->get($this->Auth->user("id"))
->contain(['Moves']);
Hope this helps.
Peace! xD

How to add index to database with belongsTo association

I'm looking for the best practice for adding an id to a database table. As an example I have a Member (model) that hasMany Recipe. The Recipe model states that it belongsTo Member:
public $belongsTo = array(
'Member' => array(
'className' => 'Member',
'foreignKey' => 'member_id',
)
);
I hoped that this would be sufficient when saving new recipes to the database, but I see that cake cannot figure out the relationship on its own because I am getting an error ("General error: 1364 Field 'member_id' doesn't have a default value") when using add:
public function add() {
if ($this->request->is('post')) {
$this->Recipe->create();
if ($this->Recipe->save($this->request->data)) {
$this->Session->setFlash(__('The recipe has been saved'));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The recipe could not be saved. Please, try again.'));
}
}
}
Now, in this case I can easily get around the problem by adding
$this->request->data['Recipe']['member_id'] = $this->Auth->user('id');
but in general the ids that I will want to add will not be stored with the Auth data. So I would like to know how to access the id when saving something that belongsTo something else.
edit: I think my question was probably not worded well enough. I will restate what I'm looking for:
Say User hasMany A, which hasMany B, which hasMany C. C belongsTo B, A, and User (table for C contains user_id, a_id, and b_id). A user logs in, and picks a certain A, and then a certain B. The user now wants to add a new C. What is the best way to get all the id values for the new C entry? Do I just set a bunch of session variables? Should they all be passed in the URL? Is there some better way?
You need to provide any information that you want to save in the database. This means you either use the Auth information like you already stated or you get the information via a form where you can select from all the members available.
Either way the information has to come from somewhere. It can not create itself out of nothing.
If the user is selecting or picking A, B or C, them, somehow you can store their data and deal with them.
Usually, the common way is using forms. If you are using Javascript, you can set hidden inputs or if you are using AJAX, just using them inside it to call the final Cake functions.
You have to see how the user picks them, and then, store that ID in some variable to play with it. POST, GET, SESSIONS, COOKIES...

CakePHP Containable on Assoicated Model

I have a setup where there are Books Users and Logs. Each Log has a Book and a User and I am trying to retrieve a list of all the books regardless of the user, but then also retrieve the Logs associated with that book (recursive is set to 1), but then only retrieving the logs of the current logged in user.
Hopefully that's clear. I tried using Containable and like so:
$this->Book->contain('Log.user_id = 2');
But unfortunately this leaves out Books for which User 2 has no logs for. Am I going about this correctly and I'm just not using containable properly, or am I doing this all wrong.
Any help is appreciated
$this->Book->Behaviors->attach('Containable');
$this->Book->find('all', array(
'contain' => array(
'Log.user_id' => 2
)
)
);

cakePHP hasOne relationship not auto completing dropdown field

I'm trying to implement a hasone relationship between 2 models, but I can't have the 'add' form autocomplete with the possible options in the second model (the one that belongsTo the first one). This is my code:
- model 1: item.php
<?php
class Item extends AppModel{
var $name = 'Item';
var $primaryKey = 'id';
var $hasOne = 'CoverImage';
}
?>
- model 2: cover_image.php
<?php
class CoverImage extends AppModel{
var $name = 'CoverImage';
var $primaryKey = 'id';
var $belongsTo = array(
'Item' => array(
'className' => 'Item',
'foreignKey' => 'item_id'
));
}
?>
- add view of model 2: add.ctp
<?php echo $this->Form->create('CoverImage',array('url' => array('controller' => 'admins', 'action' => 'add')));?>
<fieldset>
<legend><?php __('Info'); ?></legend>
<?php
echo $this->Form->input('item_id');
echo $this->Form->input('description');
?>
</fieldset>
<?php echo $this->Form->end(__('Create', true));?>
For what I see in Cake's documentation, with this relationship, in the add view I should see a dropdown list in the item_id field to be able to select to which item does this CoverImage belongs to, but the dropdown is empty (and yes, I have some items in the items table already).
Maybe I'm missing something or I've done something wrong, but I can't figure it out. Thanks so much in advance for any clues!
EDIT
One think I've just realized is that if I do this:
echo $this->Form->input('item_id', array('type'=>'text'));
instead of this:
echo $this->Form->input('item_id');
I can add/edit the *item_id* field, I can see its value in the text box. However, if I leave the other one, I just see an empty dropbox and when I try to add/edit a CoverImage, it doesn't work, it just shows an empty white page, not even with errors...
Maybe this is a lead to something...
In order for that to work you have to create a list of possible options in the controller. That does not happen automatically.
public function add() {
$items = $this->CoverImage->Item->find('list');
$this->set(compact('items'));
}
The FormHelper only automatically infers that the field item_id should be populated by the options in the variable $items (plural, no _id).
Do be careful that Items that already haveOne CoverImage should not be part of that list. find('list', array('conditions' => array('CoverItem.id' => null))) will probably* take care of that, but you'll need to recheck just before saving as well, or you need to rethink your associations.
* Not sure off the top of my head whether that'll work for 'list' searches.
EXCELLENT QUESTION. You've run afoul of a disingenuous feature of Cake's associations:
Considering you defined the relationship as hasOne? Guessing at the trace but Cake probably even correctly inferred your preference for list functionality. You got your automagic list...
...of One.
$hasOne is pretty exclusive like that. It "uses up" those "has" relationships (it's makes the relationship a de facto Singleton - so Users only have 1 Profile <-> Profile only has 1 User). Consider - Database can have many configurations, but Dbo will only ever have one Connection at a time and Connection will only have one Dbo. Thus -> hasOne is for marrying two Models til die() do they part.
-- So it doesn't get used nearly as much as hasMany and belongsTo.
For your purpose, you probably want to change to a different association.
Adding an additional $this->Item->find doesn't really fix what's wrong (and I wouldn't recommend it, unless you're mostly done with both models/controllers, or you actively want things to start getting weird fast.)
Also, changing how you call the Form Helper methods - if you return a 'list' type fetch from a find, Cake will automatically produce an option list out of it. What's actually happening is, you're sneaking around your Model on a very thin margin of View functionality. That's why specifying the input type to "break the magic" tends to be discouraged (which, you totally can if you want. Just understand what's actually happening, or: see, weird, fast.)
But you might want to rethink how you've associated your models - wouldn't it also be correct to say, each Item belongsTo a CoverImage (same as each CoverImage belongs to an Item) -- because you have a form expressly permitting a CoverImage to select an Item, any Item, to be displayed with? You'll probably get better results.
HTH. :)

paginating habtm relations

got this situation. Reports habtm users. So Im trying to paginate just the Reports that are linked to the Auth user... I read when you have a habtm relationship you have to bind the model temporarily using 'hasOne' like this:
function index(){
$conditions=array('ReportsUser.user_id'=>$this->Auth->User('id'), 'ReportsUser.report_id'=>'Report.id');
$this->beforeFind();
$this->Report->recursive=0;
$this->set('reports',$this->paginate($conditions));
}
function beforeFind()
{
$this->Report->bindModel('hasOne'=>array('ReportsUser'), false);
}
so here is the issue... that doesn't work...
that give me no results... I already checked the database for user having any Report, and i logged in with one of those user...
any suggestions?
GOT IT!!
$conditions=array('ReportsUser.user_id'=>$this->Auth->User('id'), 'ReportsUser.report_id'=>'Report.id');
i just had to remove 'ReportsUser.report_id'=>'Report.id' cuz cake was searching for it for a second time... so i just left
$conditions=array('ReportsUser.user_id'=>$this->Auth->User('id'));
and i add
$this->Report->bindModel('hasOne'=>array('ReportsUser'**=>array('className'=>'ReportsUser', 'foreignKey'=>'report_id')**), false);

Resources