unique in den rules

Hallo,

ich habe ein Problem mit dem Validator unique in den rules.

Ich möchte das drei Felder in meiner Tabelle unique sind: class, lang, form

Meine Rules müsste demnach so aussehen:


public function rules()

{

	// NOTE: you should only define rules for those attributes that

	// will receive user inputs.

	return array(

            array('class, lang, form', 'unique'),

	);

}

Demnach müsste folgendes gültig sein:


Auto, Englisch, Rover

Auto, Englisch, Rolls

Auto, Englisch, Mini

Auto, Deutsch, Mercedes

Wenn ich aber


Auto, Englisch, Mini

einfüge, dann erhalte ich die Fehlermeldung




    * Wortart "Auto" ist bereits vergeben.

    * Sprache "Englisch" ist bereits vergeben.



Wer kann mir da weiterhelfen?

Du meinst, dass die Kombination aus diesen drei Attributen unique ist, richtig? Der UniqueValidator prüft nur, ob einzelne Attribute noch nicht existieren. D.h. du wirst dir wohl am besten eine eigene Validierungsfunktion basteln müssen.

schade ;)

Wäre aber sicherlich ein nützlicher Validator.

Danke Mike!

Das ist prinzipiell nicht so einfach: Yii’s rules() sind so angelegt, dass jeder Validator auf alle angegebenen Attribute einmal angewendet wird. Hier müsste man aber einen Validator auf eine Kombination aus mehreren Attributen anwenden.

IMO ist das noch ein kleiner Schwachpunkt in der aktuellen Implementierung. Es erschwert auch so einfache Dinge wie "Bitte mindestens eines der folgenden Felder ausfüllen". Andererseits sind eigene Validatormethoden schnell geschrieben. Eine Lösung gibts also immer.

Ich habe mir grad folgendes durch gelesen

http://www.yiiframework.com/doc/guide/1.1/en/form.model#declaring-validation-rules

Wenn ich das Beispiel benutze und print_r($attribute) in der Validation authenticate mache, dann gibt er mir nur password aus und das obwohl ich zwei Attribute in der Rule habe?!




    public function rules()

    {

        return array(

            array('username, password', 'required'),

            array('rememberMe', 'boolean'),

            array('password, zweiter Parameter', 'authenticate'),

        );

    }

 

    public function authenticate($attribute,$params)

    {

        print_r($attribute);

        $this->_identity=new UserIdentity($this->username,$this->password);

        if(!$this->_identity->authenticate())

            $this->addError('password','Incorrect username or password.');

    }



Jo, genau das hab ich versucht oben zu erklären: Jeder Validator wird auf jedes zu validierende Attribut einzeln angewendet, auch wenn eine ganze Liste an Attributen in rules() aufgeführt wird. Und genau deshalb ist die gleichzeitige Validierung mehrerer Attribute mit einem einzigen Validator erst mal nicht so easy.

Ja, aber wenn ich print_r($attribute) mache und jedes einzelne Attribute überprüft wird, dann müsste print_r zwei mal ausgegeben werden.

einmal für password, einmal für "zweiter Parameter", da der Validator ja für jedes Attribute aufgerufen wird?!

Welche Alternative gibt es denn dieses Problem nun zu lösen?

Nimm mal ein existierendes Attribut statt "zweiter Parameter". Bin nicht sicher, aber evtl. wird das geprüft.

Alternative in deinem Fall ist z.B. sowas:




public function einValidator($a,$p)

{

    $condition='class=? AND lang=? AND form=?';

    if (Blabla::model()->exists($condition, array($this->class, $this->lang, $this->form)))

        $this->addError('class','Eintrag schon vorhanden');

}



Das ist aber nur der grobe Ansatz. Du musst noch prüfen, ob das ein neuer Datensatz ist, und wenn nicht, die Condition so ändern, dass nur Records mit unterschiedlichem Pk geprüft werden.

Diesen Validator solltest du natürlich nur für 1 Attribut verwenden, sonst wird die selbe SQL-Abfrage mehrmals aufgerufen.