在CakePHP中寻找战士的战斗力

时间:2013-01-14 21:29:02

标签: cakephp relationship

我有两个模型:FightFighter。我的Fight模型有两个belongsTo关系:

<?php
class Fight extends AppModel {
    public $belongsTo = array(
        'FighterA' => array(
            'className' => 'Fighter',
            'joinTable' => 'fighters',
            'foreignKey' => 'fighter_a_id'
        ),
        'FighterB' => array(
            'className' => 'Fighter',
            'joinTable' => 'fighters',
            'foreignKey' => 'fighter_b_id'
        )
    );
}

这样我可以设置两名参加战斗的战士。但是,在我的Fighter模型中,我很难弄清楚如何设置关系的另一面。

我知道我想查找fighter_a_idfighter_b_id列等于战斗机ID的所有战斗,但无法将其转换为模型中的关系。

我试过了:

<?php
class Fighter extends AppModel {
    public $hasMany = array(
        'Fight' => array(
            'conditions' => array(
                'OR' => array(
                    'Fight.fighter_a_id' => 'Fighter.id',
                    'Fight.fighter_b_id' => 'Fighter.id'
                )
            )
        )
    );
}

但CakePHP抛出一个错误,它仍在尝试查询它自动生成的(不存在的)fighter_id,将生成的WHERE子句与OR子句I'相结合如上所述。

  

错误:SQLSTATE [42S22]:未找到列:1054'字段列表'中的未知列'Fight.fighter_id'

生成的SQL语句:

  

SELECT Fight.id, Fight.fighter_a_id, Fight.fighter_b_id, Fight.event_id, Fight.weight_division_id, Fight.rounds, Fight.rounds_length, Fight.winner, Fight.winning_round, Fight.winning_time, Fight.win_method, Fight.fighter_id FROM fights AS Fight WHERE ((Fight.fighter_a_id = 'Fighter.id') OR (Fight.fighter_b_id = 'Fighter.id')) AND Fight.fighter_id = (1)

当从fighters表中查找记录时,我还要列出相关的Fight模型(按时间顺序排列,但由于与此问题无关而在另一列中处理)。

2 个答案:

答案 0 :(得分:0)

请勿在战斗机模型中设置条件。使模型简单:

class Fighter extends AppModel {
  var $hasMany = 'Fight';
}

然后在你的控制器中做逻辑并为战斗机进行战斗:

public function index($id = null) {     
        if (!$id) {
        }
        $fighter = $this->Fighter->findById($id);
        if (!$project) {
            throw new NotFoundException(__('Invalid fighter'));
        } else {
            $this->set('fighter', $fighter);

            $fights = $this->Fighter->Fight->find('all', array('conditions' => array(
            'OR' => array(
                'Fight.fighter_a_id' => 'Fighter.id',
                'Fight.fighter_b_id' => 'Fighter.id'
            )
        )));
            $this->set('fights', $fights);
        }
}

答案 1 :(得分:0)

你需要添加一个额外的表来保存哪个战士属于战斗,并将其限制为每次战斗2个记录。或者,您必须有两个belongsTo关联。

有两个belongsTo关联,Fight模型看起来像这样。

class Fighter extends AppModel {
    public $hasMany = array(
        'FightA' => array(
             'className'=>'Fight',
             'foreignKey'=>'fighter_a_id'
        ),
        'FightB' => array(
             'className'=>'Fight',
             'foreignKey'=>'fighter_b_id'
        )
    );
}

然后,您可以将FightA和FightB的两个关联结果合并到一个名为Fight的列表中。在控制器中执行此操作,或者在模型中执行afterFind回调。

我认为可以这样做。

 $fights = $this->Fighter->find(....);
 $fights['Fighter']['Fight'] = $fights['Fighter']['FightA']+$fights['Fighter']['FightB'];

另一种方法是添加另一个表来将战士与战斗联系起来。你可以把这个表称为fight_members。

这将是一个简单的表格。

CREATE  TABLE `fight_members` (
  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
  `fighter_id` INT UNSIGNED NOT NULL ,
  `fight_id` INT UNSIGNED NOT NULL ,
PRIMARY KEY (`id`) );

您现在可以找到战斗机所属的所有战斗。

class Fighter extends AppModel {
    public $hasMany = array('FightMember');
}

class Fight extends AppModel {
     public $hasMany = array('FightMember');
);

class FightMember extends AppModel {
     public $belongsTo=array('Fight','Fighter');
);