Phalcon : 저장하기 전에 관련 개체를 가져 오거나 유효성을 검사하는 방법?
-
21-12-2019 - |
문제
모델 오디오와 모델 오디오 카테고리가 있습니다.
오디오 객체를 저장하면 적어도 1 개의 AudioCategory가 연결되어 있음을 확인하고 싶습니다.
나는 사용자 정의 유효성 검사기를 만들었습니다.
유효성 검사기에서 $ AUDIO-> getRelated ()를 사용해 보았지만 정보에 대한 데이터베이스에서 가져 오려고 계속합니다. 유효성 검사는 저장하기 전에 발생하기 때문에 (훌륭함) 빈 목록을 받으면 내 유효성 검사기가 항상 false를 반환합니다.
저장하지 않고 오디오 객체를 인쇄 할 때 오디오 객체 (print_r ($ audio)의 필드에서 내 audiocorgory를 볼 수 있습니다.) :
[_RELATED : 보호]=> 배열
(
[Audiocategory]=> 어레이
(
[0]=> GRQ \ AUDIO \ Audiocategory Object ([...])
[1]=> GRQ \ AUDIO \ 오디오 카테고리 개체 ([...])
)
)
$ AUDIO -> Audiocategory를 직접 인쇄하려고하면 알림을받습니다.
정의되지 않은 속성에 대한 액세스 GRQ \ AUDIO \ AUDIO :: Audiocorgy
아무것도 반환되지 않습니다.
$ audio-> getRelated ()를 호출하면 phalcon \ mvc \ model \ resultset \ simple 형식의 _Result 유형의 객체를 얻습니다. (이는 데이터베이스에서 검색되고 검색 한 이후로 논리가 있기 때문에 ...)
그러므로 내 질문은 다음과 같습니다. 저장하기 전에 관련 필드를 어떻게 얻고 유효성을 검사 할 수 있습니까?
여기에 내 (단축) 컨트롤러 테스트가 있습니다 :
$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();
.
여기에 (단축) 오디오 모델이 있습니다.
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;
}
}
.
여기에 (단축) 오디오 카테고리 모델입니다.
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'
));
}
}
.
여기에 내 사용자 정의 유효성 검사기가 작동하지 않으며 항상 false를 항상 반환합니다.
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;
}
}
. 해결책
그래서, 나는 이것을 달성하는 방법을 발견했다.최선의 방법이지만 작동하는 것이 확실하지 않습니다.
값이 보호되므로 내 객체에서 그들을 노출해야했습니다.
그래서 나는 자신을 확장 할 기본 모델을 만들었습니다.
기본 모델 :
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;
}
}
.
그런 다음 오디오 클래스가 내 기본 모델에서 확장되도록 변경했습니다.
오디오 모델 (간체) :
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;
}
}
.
내 오디오 카테고리 모델 (단순화 된)은 거의 동일하게 유지되었습니다.
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'
));
}
}
.
및 My Validator는 이제 getInternalReleDate를 사용하여 유효성을 검사합니다.
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;
}
}
.