Question

J'ai un modèle audio et un modèle audioCategory.
Lorsque je sauvegarde l'objet audio, je souhaite valider qu'il existe au moins 1 audiocategory qui y est attaché.

J'ai créé un validateur personnalisé pour cela.
J'ai essayé d'utiliser le $ audio-> GetRelated () dans le validateur, mais il continue à essayer de chercher dans la base de données pour connaître les informations. Étant donné que la validation se produit avant d'économiser (ce qui est génial), je reçois une liste vide, mon validateur revient donc toujours faux.

Lorsque j'imprime l'objet audio sans enregistrer, je peux voir mon audiocategory sur le terrain _Related de l'objet audio (print_r ($ audio);):
[Related: Protégé]=> Array
( [Audiocategory]=> Array
(
[0]=> GRQ \ Audio \ AudiOcAgory Object ([...])
[1]=> Objet Grq \ Audio \ AudioCategory ([...])
)
)

Si j'essaie d'imprimer directement audio-> AudioCategory directement, je reçois un avis:
Accès à la propriété non définie Grq \ Audio \ Audio :: Audiocategory
et rien n'est retourné.

Si j'appelle $ Audio-> GetRelated (), je reçois un objet de type Phalcon \ mvc \ Modèle \ Restructeurs \ Simple avec un _Result vide. (Qui est logique, puisqu'il est allé et recherché dans la base de données ...)


Par conséquent, ma question est:
Comment puis-je obtenir et valider les champs associés avant de les sauver?


Voici mon test de contrôleur (raccourci):

    $audioCategory = new AudioCategory();
    $audioCategory->categoryId = 1;
    $arAudioCategory[0] = $audioCategory; 

    $audioCategory = new AudioCategory();
    $audioCategory->categoryId = 2;
    $arAudioCategory[1] = $audioCategory;

    $audio = new Audio();
    [...other fields initialization...]
    $audio->audiocategory = $arAudioCategory;
    $audio->save();

Voici le modèle audio (raccourci):

namespace GRQ\Audio;
use GRQ\Validator\PresenceOfRelationValidator;
class Audio extends \Phalcon\Mvc\Model {
/**
 * @Primary
 * @Identity
 * @Column(type="integer", nullable=false)
 */
public $id = 0; 
/**
 * @Column(type="integer", nullable=false)
 */
public $createdAt = 0;

[...other fields all reflecting the database...]

public function initialize() {
    $this->setSource ( "audio" );

    // table relationships
    $this->hasMany ( "id", "GRQ\Audio\AudioCategory", "audioId", array(
            'alias' => 'audiocategory'
    ) );
}

public function validation() {      
    [...other validations...]

    $this->validate ( new PresenceOfRelationValidator ( array (
            "field" => "audiocategory" 
    ) ) );

    return $this->validationHasFailed () != true;
}
}

Voici le modèle (raccourci) Catégorie audio:

namespace GRQ\Audio;    
class AudioCategory extends \Phalcon\Mvc\Model {
/**
 * @Primary
 * @Identity
 * @Column(type="integer", nullable=false)
 */
public $id = 0; 
/**
 * @Column(type="integer", nullable=false)
 */
public $audioId = 0;    
/**
 * @Column(type="integer", nullable=false)
 */
public $categoryId = 0;

public function initialize(){
    $this->setSource("audiocategory");
    //table relationships
    $this->belongsTo("audioId", "GRQ\Audio\Audio", "id", array(
            'alias' => 'audio'
    ));
}
}

Voici mon validateur personnalisé (qui ne fonctionne pas et retourne toujours faux):

namespace GRQ\Validator;

use Phalcon\Mvc\Model\Validator;
use Phalcon\Mvc\Model\ValidatorInterface;

class PresenceOfRelationValidator extends Validator implements ValidatorInterface {
public function validate($model){
    $field = $this->getOption('field');
    $message = $this->getOption('message');
    if (!$message) {
        $message = 'The required relation '.$field.' was not found';
    }

    $value = $model->getRelated($field);

    if (count($value) == 0) {
        $this->appendMessage(
                $message,
                $field,
                "PresenceOfRelation"
        );
        return false;
    }
    return true;
}
}

Était-ce utile?

La solution

Alors, j'ai trouvé un moyen de y parvenir.Pas sûr que ce soit le meilleur moyen, mais ça marche:
Étant donné que les valeurs sont protégées, je devais les exposer de mon objet.
J'ai donc créé un modèle de base à partir de laquelle s'étender moi-même:

Modèle de base:

namespace GRQ;
class BaseModel extends \Phalcon\Mvc\Model {

/**
 * This function should be used to get the data in the _related field directly.
 * It is very useful if you need to validate the presence of a relation BEFORE saving in the database.
 * To initialize the field with the database content, use $this->getRelated().
 */
public function getInternalRelated(){
    return $this->_related;
}   
}

Puis j'ai changé ma classe audio pour s'étendre de mon modèle de base:

modèle audio (simplifié):

namespace GRQ\Audio;

use Phalcon\Mvc\Model\Validator\Numericality;
use GRQ\Validator\MinValueValidator;
use GRQ\Validator\PresenceOfRelationValidator;

class Audio extends \GRQ\BaseModel {
/**
 * @Primary
 * @Identity
 * @Column(type="integer", nullable=false)
 */
public $id = 0;

/**
 * @Column(type="string", length=255, nullable=false)
 */
public $title = '';

public function initialize() {
    $this->setSource ( "audio" );

    // table relationships
    $this->hasMany ( "id", "GRQ\Audio\AudioCategory", "audioId", array(
            'alias' => 'audiocategory'
    ) );
}

public function validation() {              
    $this->validate ( new PresenceOfRelationValidator ( array (
            "field" => "audiocategory" 
    ) ) );

    return $this->validationHasFailed () != true;
}
}

Mon modèle AudioCategory (simplifié) est resté à peu près la même chose:

namespace GRQ\Audio;

use Phalcon\Mvc\Model\Message;

class AudioCategory extends \GRQ\BaseModel {
/**
 * @Primary
 * @Identity
 * @Column(type="integer", nullable=false)
 */
public $id = 0;

/**
 * @Column(type="integer", nullable=false)
 */
public $audioId = 0;

/**
 * @Column(type="integer", nullable=false)
 */
public $categoryId = 0;

public function initialize()
{
    $this->setSource("audiocategory");
    //table relationships
    $this->belongsTo("audioId", "GRQ\Audio\Audio", "id", array(
            'alias' => 'audio'
    ));
}
}

Et mon validateur utilise maintenant la méthode Getinternalrelated pour valider:

namespace GRQ\Validator;

use Phalcon\Mvc\Model\Validator;
use Phalcon\Mvc\Model\ValidatorInterface;

class PresenceOfRelationValidator extends Validator implements ValidatorInterface {
public function validate($model){
    $field = $this->getOption('field');
    $message = $this->getOption('message');
    if (!$message) {
        $message = 'The required relation '.$field.' was not found';
    }

    $value = $model->getInternalRelated();

    if (count($value[$field]) == 0) {
        $this->appendMessage(
                $message,
                $field,
                "PresenceOfRelation"
        );
        return false;
    }
    return true;
}
}

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top