間違っている場合は修正してください。しかし、Eloquentモデルには大量更新などはないと思います。
すべての行に対してクエリを発行せずにDBテーブルを一括更新する方法はありますか?
たとえば、次のような静的メソッドがあります
User::updateWhere(
array('age', '<', '18'),
array(
'under_18' => 1
[, ...]
)
);
(はい、それはばかげた例ですが、あなたは絵を手に入れます...)
なぜそのような機能が実装されていないのですか?このようなことが起こった場合、私は非常に幸せになるだろうか?
私(開発者)は、次のように実装したくありません。
DB::table('users')->where('age', '<', '18')->update(array('under_18' => 1));
プロジェクトが大きくなると、プログラマーが将来テーブル名を変更する必要があり、テーブル名を検索して置換できないためです!
この操作を実行する静的な方法はありますか?存在しない場合は、Illuminate\Database\Eloquent\Model
そのようなことを達成するクラス?
大量の更新/挿入機能については、それが要求されましたが、Taylor Otwell(Laravelの著者)は、ユーザーが代わりにクエリビルダーを使用することを推奨しています。 https://github.com/laravel/framework/issues/1295
通常、モデルはIlluminate\Database\Eloquent\Modelを拡張する必要があります。次に、エンティティiselfにアクセスします。たとえば、これがある場合:
<?php
Use Illuminate\Database\Eloquent\Model;
class User extends Model {
// table name defaults to "users" anyway, so this definition is only for
// demonstration on how you can set a custom one
protected $table = 'users';
// ... code omited ...
#2を更新
クエリビルダーに頼る必要があります。テーブルの命名の問題をカバーするには、getTable()メソッドを使用して動的に取得できます。この唯一の制限は、この関数を使用する前にユーザークラスを初期化する必要があることです。クエリは次のようになります。
$userTable = (new User())->getTable();
DB::table($userTable)->where('age', '<', 18)->update(array('under_18' => 1));
これにより、テーブル名はユーザーモデルのコントローラーになります(上記の例に示すように)。
#1を更新
これを行う他の方法(状況によっては効率的ではありません)は次のとおりです。
$users = User::where('age', '<', 18)->get();
foreach ($users as $user) {
$user->field = value;
$user->save();
}
このように、テーブル名はユーザークラスに保持され、開発者はそれを心配する必要がありません。
おそらくこれは数年前には不可能でしたが、Laravelの最近のバージョンでは間違いなく次のことができます:
User::where('age', '<', 18)->update(['under_18' => 1]);
update
を呼び出す前にwhereメソッドが必要であることに注意してください。
データベーストランザクションを使用して、複数のエンティティを一括で更新します。トランザクションは、更新機能が終了したときにコミットされるか、例外がその間に発生した場合はロールバックされます。
https://laravel.com/docs/5.4/database#database-transactions
たとえば、これは、1回の一括更新で記事のマテリアライズドパスナメクジ( https://communities.bmc.com/docs/DOC-9902 )を再生成する方法です。
public function regenerateDescendantsSlugs(Model $parent, $old_parent_slug)
{
$children = $parent->where('full_slug', 'like', "%/$old_parent_slug/%")->get();
\DB::transaction(function () use ($children, $parent, $old_parent_slug) {
/** @var Model $child */
foreach ($children as $child) {
$new_full_slug = $this->regenerateSlug($parent, $child);
$new_full_title = $this->regenerateTitle($parent, $child);
\DB::table($parent->getTable())
->where('full_slug', '=', $child->full_slug)
->update([
'full_slug' => $new_full_slug,
'full_title' => $new_full_title,
]);
}
});
}
@metamakerの答えを少し修正:
DB::beginTransaction();
// do all your updates here
foreach ($users as $user) {
$new_value = Rand(1,10) // use your own criteria
DB::table('users')
->where('id', '=', $user->id)
->update([
'status' => $new_value // update your field(s) here
]);
}
// when done commit
DB::commit();
1つのDBトランザクションで1ミリオンの異なる更新を取得できるようになりました
laravel 5.8では、次のように一括更新を実行できます。
User::where('id', 24)->update (dataAssociativeArray) ;