rules unique и значение array

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
osi322
Сообщения: 10
Зарегистрирован: 2016.04.06, 08:12

rules unique и значение array

Сообщение osi322 »

В таблице пара уникальных значений Id_matetial и serial
В форме serial[] является массивом(serial).
Пишу правило

Код: Выделить всё

['serial', 'each', 'rule' => ['string', 'max' => 255]],
Дальше хотелось это..

Код: Выделить всё

[['Id_matetial ', 'serial'],'unique', 'targetAttribute' => ['Id_matetial ', 'serial']]
но зашел в тупик, так как serial является массивом(значение не верно), как сделать проверку на уникальность в таком случае?
Аватара пользователя
Alexum
Сообщения: 683
Зарегистрирован: 2016.09.26, 10:00

Re: rules unique и значение array

Сообщение Alexum »

Правило можно составить, но оно не защитит от наличия дубликатов внутри передаваемого массива. Лучше напишите отдельный валидатор, в котором:
а) пройдитесь по всем элементам массива и проверьте уникальность между собой
б) сформируйте поисковый запрос и стукнитесь в БД с параметрами id_matetial и serial, которые собираетесь сохранить.
osi322
Сообщения: 10
Зарегистрирован: 2016.04.06, 08:12

Re: rules unique и значение array

Сообщение osi322 »

Спасибо за ответ.
Пункт б) решается 1 строчкой :)

Код: Выделить всё

['serial','each','rules'=>['unique','targetAttribute'=>['serial','id_material']]]
Только вот each возвращает ко всем input вида name='Xxxx[serial][][/b]' все поля сбрасывает и и ко всем ошибку выводит :|
osi322
Сообщения: 10
Зарегистрирован: 2016.04.06, 08:12

Re: rules unique и значение array

Сообщение osi322 »

И так получилось следующее
Пример:
контроллер

Код: Выделить всё

class TestController extends \yii\web\Controller
{
    public function actionIndex()
    {
        $model= new \frontend\models\material\TestModel();
        if ($model->load(Yii::$app->request->post()) && $model->act()) {
             $model=$model->act();
        }
            return $this->render('index', [
              'model' => $model,   
            ]);
    }

}
модель

Код: Выделить всё

namespace frontend\models\material;

use Yii;

/**
 * This is the model class for table "test".
 *
 * @property int $id
 * @property int $number
 * @property string $name
 */
class TestModel extends \yii\db\ActiveRecord
{
    /**
     * {@inheritdoc}
     */
    public static function tableName()
    {
        return 'test';
    }

    /**
     * {@inheritdoc}
     */
    public function rules()
    {
        return [
            [['number', 'name'], 'required'],
            [['number'], 'integer'],
            //[['name'], 'string', 'max' => 80],
            //[['number', 'name'], 'unique', 'targetAttribute' => ['number', 'name']],
            ['name', 'each','rule'=>['string']],
            ['name','my'],
            ['name','each','rule'=>['unique', 'targetAttribute' => ['number', 'name']]],
        ];
    }

    /**
     * {@inheritdoc}
     */
    public function attributeLabels()
    {
        return [
            'id' => 'ID',
            'number' => 'Number',
            'name' => 'Name',
        ];
    }
    
    public function my()
    {
        $error=array();
        $as=array();
        foreach ($this->name as $key => $value) {
           if(array_search($value, $as)===false){
               $as[]=$value;
           }
           else {
              $error[]=$key;//пишем ключи у каких полей повторения
           }          
        }
            $this->addErrors(['name'=>$error]);
        
    }

    public function act()
    {        
        if (!$this->validate()) {
            return null;
        }
        
        return $this;// фиг знает что возврощать
    }
}
вид

Код: Выделить всё

use yii\helpers\Html;
use yii\widgets\ActiveForm;
/* @var $this yii\web\View */
?>
<h1>test/index</h1>

<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'number')->input('number')?>
<?php
for ($index = 0; $index < 3; $index++) {
    echo $form->field($model, 'name[]')->textInput();
}
?>
<?= Html::submitButton('Создать', ['class' => 'btn btn-success','id'=>'create-bt']) ?>
 <?php ActiveForm::end(); ?>
В итоге правила работают и на повторение и на пару ключ значения в бд(idx-name-number; unique), но если вдруг срабатывает валидация то все поля name[] становятся пустыми и у всех одна ошибка.. В какую сторону копать чтобы при срабатывании валидации, поля не становились пустыми а помечались красным, что в этом поле повторение или уже существует в бд(эти правила работают)...
Аватара пользователя
Alexum
Сообщения: 683
Зарегистрирован: 2016.09.26, 10:00

Re: rules unique и значение array

Сообщение Alexum »

Проверьте, сколько запросов к БД делает такая конструкция ( ['name','each','rule'=>['unique', 'targetAttribute' => ['number', 'name']]],) и не оптимальнее ли одним запросом в своём методе это делать.
osi322
Сообщения: 10
Зарегистрирован: 2016.04.06, 08:12

Re: rules unique и значение array

Сообщение osi322 »

А как по другому проверить значение на уникальность?
к примеру
нужно ввести несколько общих параметров, и два уникальных

Код: Выделить всё

array{
	0=>[
	p1=>1,
	p2=>1,
	number=>2,
	name=>'a'
	}
	1=>[
	p1=>1,
	p2=>1,
	number=>1,
	name=>'a'
	}
	1=>[
	p1=>1,
	p2=>1,
	number=>1,
	name=>'v'
	}
}
одним запросом я понимаю так

Код: Выделить всё

select * from test where (number='' and name='') or (number='' and name='')  or....
потом циклы писать на сравнение массива модели и на вывод запроса
Это разве будет логичней?
osi322
Сообщения: 10
Зарегистрирован: 2016.04.06, 08:12

Re: rules unique и значение array

Сообщение osi322 »

Хоты Вы совершенно правы. Экономней 1 запрос, к тому же, чаще всего он будет равен null.
А вот на счет подсветки input.. еще думаю
Аватара пользователя
Alexum
Сообщения: 683
Зарегистрирован: 2016.09.26, 10:00

Re: rules unique и значение array

Сообщение Alexum »

У вас number один на всех, поэтому конструкция запроса проще, да и кроме имён дубликатов в ответ ничего не нужно SELECT name FROM test WHERE number = ...' AND name IN ('...','...','...')
потом циклы писать на сравнение массива модели и на вывод запроса
А что там много писать? Получаете из БД массив имён-дубликатов и на них же ругаетесь. Сравнивать с моделью уже не надо, вы же поисковый запрос для этого и составляете.
osi322
Сообщения: 10
Зарегистрирован: 2016.04.06, 08:12

Re: rules unique и значение array

Сообщение osi322 »

Вы поняли не правильно(наверное плохо выражаюсь) я хочу понять как yii2 работает с множеством insert... для этого команда только одна, если не ошибаюсь

Код: Выделить всё

createCommand()->batchInsert()
что я хочу сделать, не 1 вставку а n количество. То есть в форме массив одноименных полей, Yii2 это позволяет сделать, а вот с валидацией не понял.
Хоть в документации написано только про checkbox[] и imageFiles[].. с ними не пробовал, но он должен возвращать какой файл не загружен.. уже пошел не туда :D
Так вот форма содержит набор name[] и number[](не важно я просто отделил и сделал 1 number, то есть form отсылает {number=>'',name=>[0=>'',1=>''....]}), валидация работает по каждому(как надо) name[], но отображает $model->errors на все name[] остальные как бы не счет.
То есть как быть в таком случае

Код: Выделить всё

for ($index = 0; $index < 3; $index++) {
    echo $form->field($model, 'number[]')->textInput()
    echo $form->field($model, 'name[]')->textInput(); 
}
и любая валидация, даже requared работает так.. 1) ввел значение в первое поле name, все остальные name зеленые 2) ввел во второе(первое пустое) все красные 3) при Post запросе все name[] пустые так как ожидает что просто name в этом случае я сделал так

Код: Выделить всё

for ($index = 0; $index < 3; $index++) {
    $val="";
    if($model->name){ // то есть если не пусто значит был Post
        $val=$model->name[$index];
    }
    echo $form->field($model, 'name[]')->textInput(['value'=>$val]); 
}
osi322
Сообщения: 10
Зарегистрирован: 2016.04.06, 08:12

Re: rules unique и значение array

Сообщение osi322 »

Пришел к такому...
view

Код: Выделить всё

<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
/* @var $this yii\web\View */
?>
<h1>test/index</h1>

<?php 
echo '<pre>';
echo \yii\helpers\VarDumper::dump($model->errors);
echo '</pre>';
$form = ActiveForm::begin();?>
<?= $form->field($model, 'number')->textInput()?>
<?php
for ($index = 0; $index < 3; $index++) {
   
    echo $form->field($model, 'name['.$index.']',)->textInput(); 
}
?>
<?= Html::submitButton('Создать', ['class' => 'btn btn-success','id'=>'create-bt']) ?>
 <?php ActiveForm::end(); ?>
<?php  ?>
model

Код: Выделить всё

    public function rules()
    {
        return [  
            ['name', 'each','rule'=>['string']],
            ['name', 'each','rule'=>['required']],
        ];
    }
   
В этом случае работает только клиентская часть валидации, а ответ сервера красит все поля
Note: EachValidator is meant to be used only in basic cases, you should consider usage of tabular input, using several models for the more complex case.
Последний раз редактировалось osi322 2018.11.12, 13:23, всего редактировалось 1 раз.
osi322
Сообщения: 10
Зарегистрирован: 2016.04.06, 08:12

Re: rules unique и значение array

Сообщение osi322 »

https://www.yiiframework.com/doc/guide/ ... ular-input
Вот оказывается как работать в yii с массивом данных модели. Тема закрыта.
Ответить