Я рассматриваю массовое задание в Laravel и пытаюсь распределить данные как для одной модели, так и для родственной модели.
class News extends Eloquent { protected $table = 'news'; protected $fillable = array( 'title', 'slug', 'author', 'img', 'content', ); public function content() { return $this->morphMany('Content', 'morphable')->orderBy('section'); } } class Content extends Eloquent { protected $table = 'contents'; protected $fillable = array( 'rawText', 'section', ); public function morphable() { return $this->morphMany(); } }
У меня есть Input:all()
выглядит следующим образом, исходя из формы:
array(6) { ["_token"]=> string(40) "irrelevant" ["title"]=> string(11) "Happy Title" ["author"]=> string(9) "Mr. Happy" ["slug"]=> string(11) "happy-title" ["img"]=> string(9) "happy.png" ["content"]=> array(1) { [0]=> array(2) { ["section"]=> string(4) "body" ["rawText"]=> string(27) "# I'm happy! ## So happy" }}}
Что мне теперь делать, чтобы фактически сохранить данные в виде двух новых строк базы данных? (один в новостях, один по содержанию)
Я думал, что теперь будет так просто:
$news = News::create(Input::all()); $news->push();
Но я явно что-то пропустил.
Я получаю сообщение об ошибке: preg_replace(): Parameter mismatch, pattern is a string while replacement is an array
Не работает ли массовое задание вообще со связанными моделями?
Или он работает нормально, но не с отношениями morphMany?
Я неправильно понял $model->push()
или $model::create
?
Заранее спасибо.
Как часто с вопросами SO, письмо и форматирование дали мне некоторое время подумать.
$input = Input::all(); $contents = Input::get('content'); unset($input['content']); $news = News::create($input); foreach ($contents as $c) { $content = Content::create($c); $news->content()->save($content); } $news->save();
с$input = Input::all(); $contents = Input::get('content'); unset($input['content']); $news = News::create($input); foreach ($contents as $c) { $content = Content::create($c); $news->content()->save($content); } $news->save();
Работает! Но чувствует себя довольно хаки. Есть ли еще .. «Красноречивый» способ массовой передачи связанных моделей?
Изменить: возможно, это, скорее всего, правильный курс действий – массовое присвоение не будет обрабатывать отношения, но, по крайней мере, я могу назначить каждую модель отдельно.
Мне просто нужно немного манипулировать входными данными, что мне, вероятно, придется делать в любом случае после того, как в формулу добавится подтверждение.
Edit2: Имея большой успех, двигая связанную модельную логику в эту модель и сохраняя ее просто, например:
$input = Input::all(); unset($input['content']); $news = News::create($input); $news = Content::updateAll($news, true); $news->save();
с$input = Input::all(); unset($input['content']); $news = News::create($input); $news = Content::updateAll($news, true); $news->save();
для создания и:
$input = Input::all(); unset($input['content']); $news = News::find($id)->fill($input); $news = Content::updateAll($news, false); $news->save();
с$input = Input::all(); unset($input['content']); $news = News::find($id)->fill($input); $news = Content::updateAll($news, false); $news->save();
для обновления .
Метод updateAll()
для всех, кто интересуется:
public static function updateAll($model, $create = false) { $contents = Input::get('content'); foreach ($contents as $k => $c) { // Save against parent model if ($create) { $content = Content::create($c); } else { $content = Content::find($k)->fill($c); } $model->content()->save($content); } return $model; }
Теперь я чувствую, что использую полную силу!