Страница 1 из 2

Сохранение связанных данных

Добавлено: 2009.08.23, 17:29
samdark
Рецепт, показывающий, как реализовать автоматическое сохранение связанных данных при сохранении модели.

http://yiiframework.ru/doc/cookbook/ru/ ... lated.data

Re: Сохранение связанных данных

Добавлено: 2009.11.12, 07:38
dimmer
Что-то у меня вообще не сохраняет связанные данные. Вот пример:

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

$book=new Book();
 $file=new File();
if(isset($_POST['Book'])){
$book->attributes=$_POST['Book'];
$book->user_id=$file->user_id=Yii::app()->user->id;
$file->magnetlink=123;
$file->id=123;
$file->book_id=123;
$book->files[]=$file;
if($book->save()) $this->redirect(array('show','id'=>$book->id));
}
$this->render('create',array('model'=>$book,'file'=>$file)); 
Во-первых не сохраняет запись файла, а во-вторых если писать со скобками $book->files[]=$file; то выдает
Indirect modification of overloaded property Book::$files has no effect
Это нормально?
Просьба сильно не ругать Yii начал изучать недавно, но он мне уже успел во многом понравиться!

Re: Сохранение связанных данных

Добавлено: 2009.11.12, 12:47
samdark
Покажите реализацию afterSave() вашей модели.

Re: Сохранение связанных данных

Добавлено: 2009.11.12, 23:39
dimmer
То есть надо ещё добавить какую-то логику в модель? Yii сам не сохраняет связанные данные? В примере в AfterSafe только раздает id-шники.

Re: Сохранение связанных данных

Добавлено: 2009.11.13, 12:25
samdark
В примере есть строчка $member->save(), которая и сохраняет связанные модели.

Re: Сохранение связанных данных

Добавлено: 2010.04.10, 16:29
makingfeels
Всех приветствую. Что-то никак не пойму,что не так делаю.
это код в actionCreate:

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

  $node=new Node;
        $numericField=new NodeNumericField;
        $stringField=new NodeStringField;
        
        if(isset($_POST['Node']))
        {
            $node->attributes=$_POST['Node'];
            $numericField->attributes=$_POST['NodeNumericField'];
            $stringField->attributes=$_POST['NodeStringField'];
            
            $node->nodeNumericFields[] = $numericField;
            $node->nodeStringFields[] = $stringField;    
            
            if($node->save()) $this->redirect('index');
            
        } 
И соотвественно в модели:

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

protected function afterSave(){
        parent::afterSave();
        foreach($this->nodeStringFields as $nodeStringField) {
            $nodeStringField->node_id = $this->id;
            $nodeStringField->save();
        }
        
        foreach($this->nodeNumericFields as $nodeNumericField) {
            $nodeNumericField->node_id = $this->id;
            $nodeNumericField->save();
        }
    }
  
запись node сохраняется,а вложенные нет,ошибок никаких не выдается.

Re: Сохранение связанных данных

Добавлено: 2010.04.11, 08:32
makingfeels
Наконец-то победил это, вопщем вся проблема была в том,что у меня почему-то не работает как на примере

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

$team->members[] = $member1;
$team->members[] = $member2; 

Работает вот так:

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

$team->members
Тоесть соотвественно в $team->members сохраняется уже массив.
(версия у меня кстати yii 1.1.1)

Re: Сохранение связанных данных

Добавлено: 2011.03.15, 12:57
Darth_Ixis
makingfeels писал(а):Наконец-то победил это, вопщем вся проблема была в том,что у меня почему-то не работает как на примере

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

$team->members[] = $member1;
$team->members[] = $member2; 
Аналогично.
Это нормальное поведение, что я не могу парными квадратными скобками создать массив / добавить элементов массиву?

Re: Сохранение связанных данных

Добавлено: 2011.05.14, 22:52
slavcodev
У меня тоже через квадратные скобки не хочет добавлять. Но решение есть:

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

$team->addRelatedRecord('members',$member1,count($team->members)); 

Re: Сохранение связанных данных

Добавлено: 2011.05.28, 12:27
ezoterik
Подскажите, а как мог бы выглядеть рецепт если нужно сохранить связи MANY_MANY? У меня скорее даже вопрос в том, что можно ли обойтись (в связывании данных при сохранении) без дополнительной модели на промежуточную таблицу в этом случае.

Re: Сохранение связанных данных

Добавлено: 2011.05.29, 01:01
samdark
Если вставлять через SQL — можно.

Re: Сохранение связанных данных

Добавлено: 2011.12.13, 22:33
IStranger
Подскажите пожалуйста... Как быть, если число членов измеряется десятками-сотнями? Смущает как-то процедурная логика (многократное сохранение в цикле).

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

        foreach($this->members as $member) {
            ...
            $member->save();
        }
 
В данном случае в рамках AR возможно ли сохранение одним "массовым" запросом, или уже DAO нужно использовать?

Re: Сохранение связанных данных

Добавлено: 2011.12.14, 00:48
samdark
DAO.

Re: Сохранение связанных данных

Добавлено: 2012.07.07, 15:47
Shlang
А как "лутше" поступить при создании новой записи? Без конструкции
$transaction=$model->dbConnection->beginTransaction();
try {
- - - -
$transaction->commit();
}
} catch (Exception $ex) {
$transaction->rollback();
return false;
}
похоже не обойтись?
Кошерный код длинным не бывает, может кто запостит чего...

Re: Сохранение связанных данных

Добавлено: 2012.10.24, 07:17
yujin1st
Подскажите как совместить данный способ вместе со связями описанными в relations()?
Ведь $team->members[] не работает при описанной связи.
К этому же вопросу можно и отнести табличные данные - хочется не "foreach" в контролере, а просто $team->attributes = $_POST['team']; $team->save();

Придумал такой костыль с объявлением свойства Team::_members, переименованием связи в membersRelated.

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

public function AfterFind(){
  if (hasRelation('membersRelated'){
  $this->_members = $this->membersRelated();
  }
}
public function getMembers(){
  return $this->_members;
}
// для того чтобы работало с табличным вводом при создании модели: $team->attributes= $_POST['Team']
public function setMembers($newMembers){
      if (is_array($newMembers) && count ($newMembers) {
      foreach ($newMembers as  $m) {
        $member = new Member();

        $member->attributes  = $m
        $this->_rentServices[] = $rs;
      }
    }
}
// вместо $team->members[] = $newMember будет $team->addMember($member)
public function addMember($member){
  $this->_members[]=$member
}
//и в afterSave() мы сохраняем
 
Но здесь:
- нет гибкости
- легко запутаться в именах
- облом при табличном редактировании тех же данных - приходиться только по одному...
- я не знаю как добавить валидацию в контроллере? Переопределять Team::validate()?
Я предполагаю, что изобретаю очередной велосипед, и наверняка есть более просто решение...

Re: Сохранение связанных данных

Добавлено: 2012.11.08, 05:58
areshetnikov
ezoterik писал(а):Подскажите, а как мог бы выглядеть рецепт если нужно сохранить связи MANY_MANY? У меня скорее даже вопрос в том, что можно ли обойтись (в связывании данных при сохранении) без дополнительной модели на промежуточную таблицу в этом случае.
Всем привет!

подниму вопрос по поводу связывания двух сущностей MANY_MANY.
Как в этом случае стоит реализовать afterSave()? Писать в таблицу связки напрямую? Есть ли в YII готовое решение? Сколько не курю форум этот и общий - не могу найти ответа.

Re: Сохранение связанных данных

Добавлено: 2012.11.08, 06:59
areshetnikov
В догонку:
Есть класс Tournament и его relations

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

    public function relations()
    {
        // NOTE: you may need to adjust the relation name and the related
        // class name for the relations automatically generated below.
        return array(
            'teams'=>array(self::MANY_MANY, 'Team', 'tr_tournament_teams(id_tournament, id_team)'),
            'teamsCount' => array(self::STAT, 'Team', 'tr_tournament_teams(id_tournament, id_team)'),
        );
    }
Есть класс Team и его relations

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

    public function relations()
    {
        // NOTE: you may need to adjust the relation name and the related
        // class name for the relations automatically generated below.
        return array(
            'tournaments'=>array(self::MANY_MANY, 'Tournament', 'tr_tournament_teams(id_team, id_tournament)'),    
        );
    }
В контроллере пишу:

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

class TournamentController extends Controller

    protected function addTeam($tournament)
    {
        $team=new Team();
        if(isset($_POST['Team']))
        {
            $team->attributes=$_POST['Team'];
            
            $team->save();
            array_push($tournament -> teams(), $team);
            array_push($team -> tournaments(), $tournament);
            $tournament->save();            
            $team->save();
        }
        return $tournament;
    }
При этом новые экземпляры Team в базе сохраняются, а связи между Team и Tournament.

Re: Сохранение связанных данных

Добавлено: 2012.11.08, 11:30
samdark
Нет, в Yii готового на тему нет, но есть http://yiiext.github.com/extensions/wit ... me.ru.html

Re: Сохранение связанных данных

Добавлено: 2012.11.11, 11:56
areshetnikov
Посмотрел, простой пример собрал за 5 минут.
Спасибо, все работает. Буду встраивать в своё приложение.

Re: Сохранение связанных данных

Добавлено: 2012.11.11, 12:01
areshetnikov
Отчего данная функциональность все еще не встроена в стандарт YII?
Кажется ведь столь полезной. Или это только с MANY_MANY такие сложности?