开发者

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'
                        )); 
}
?>
开发者_JAVA百科

- 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. :)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜