php Laravel 无需两次查询即可创建或更新
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23315949/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Laravel create or update without two queries
提问by mpen
I'm trying to use one form for both creates and updates. Both actions save through this method:
我正在尝试使用一种形式进行创建和更新。这两个操作都通过此方法保存:
public function store() {
$data = Input::all();
$data['company_id'] = Auth::user()->company_id;
$validator = Validator::make($data, Feature::$rules);
if($validator->fails()) {
return Redirect::back()->withErrors($validator)->withInput();
}
Feature::firstOrNew(['id' => Input::get('id')])->update($data);
return Redirect::route('features.index');
}
How can I rewrite this line:
我怎样才能重写这一行:
Feature::firstOrNew(['id' => Input::get('id')])->update($data);
So that it doesn't fetch the object from the database first? There's no need for that; I'm not doing anything with it. It should either issue a INSERT
if Input::get('id')
is set, or an UPDATE
if it's not.
这样它就不会先从数据库中获取对象?没有这个必要;我不会用它做任何事情。它应该要么发出INSERT
ifInput::get('id')
设置,要么发出if UPDATE
。
采纳答案by Vladislav Rastrusny
If you have all fields unguarded in your model, I think you can do it like this:
如果您的模型中的所有字段都不受保护,我认为您可以这样做:
$feature = new Feature($data);
$feature->exists = Input::has('id');
$feature->save();
If you have some guarded fields, then you can unguard it first:
如果你有一些受保护的字段,那么你可以先解除它:
$feature = new Feature();
$feature->unguard();
$feature->fill($data);
$feature->exists = Input::has('id');
$feature->reguard();
$feature->save();
The reguard()
call is not actually needed if you don't do anything else with the model.
的reguard()
,如果你没有做任何其他与该模型实际上不需要调用。
回答by Keith Holliday
This is what I use:
这是我使用的:
Model::updateOrCreate(
['primary_key' => 8],
['field' => 'value', 'another_field' => 'another value']
);
The second parameter is an array of the data for the model you want to save.
第二个参数是要保存的模型的数据数组。
回答by yajra
I used to have this problem and created an accepted pull requeston Laravel which you can use. Try the code below. The method you will basically need is the findOrNew
.
我曾经遇到过这个问题,并在 Laravel 上创建了一个可接受的拉取请求,您可以使用它。试试下面的代码。您基本上需要的方法是findOrNew
.
public function store($id=0)
{
$user = User::findOrNew($id);
$data = Input::all();
if (!$user->validate($data)) {
return Redirect::back()->withInput()->withErrors($user->errors);
}
$user->fill($data);
$user->save();
return Redirect::to('/')->with('message','Record successfully saved!');
}
My model uses self validation but you can create your own validation like the one you have now.
我的模型使用自我验证,但您可以像现在一样创建自己的验证。
回答by Majbah Habib
Find or New based on primary key id
根据主键id查找或新建
$data = Input::all();
$user = User::findOrNew($id); // if exist then update else insert
$user->name= $data['user_name'];
$user->save();
First or New based on non-primary key single filed
First 或 New 基于非主键单一归档
$user = User::firstOrNew(['field' => $data['value'] ]);
$user->name= $data['user_name'];
$user->save();
First or New based on non-primary key multiple filed
First 或 New 基于非主键多次归档
$user = User::firstOrNew([
'field1'=>$data['value1'],
'field2'=>$data['value2']
]);
$user->name= $data['user_name'];
$user->save();
回答by peaceman
If you are following the resource router methodology of laravel, you should use a separate method named update to update your model, so the separation can be done by the framework. With this it is still possible to reuse your form.
如果你遵循 laravel 的资源路由方法,你应该使用一个名为 update 的单独方法来更新你的模型,这样分离可以由框架完成。有了这个,仍然可以重用您的表单。
If you really want to avoid a new method to update the model, you could rewrite it as follows:
如果你真的想避免更新模型的新方法,你可以按如下方式重写它:
public function store() {
$model = Input::has('id')
? ModelClass::findOrFail(Input::get('id'))
: new ModelClass;
$inputData = Input::all();
$validator = Validator::make($inputData, ModelClass::$rules);
if ($validator->fails()) {
return Redirect::back()
->withErrors($validator)
->withInput();
}
$model->fill($inputData);
$model->save();
return Redirect::route('modelclass.index');
}
回答by The Alpha
You may try this:
你可以试试这个:
$data = Input::except('_token');
$newOrUpdate = Input::has('id') ? true : false;
$isSaved = with(new Feature)->newInstance($data, $newOrUpdate)->save();
If $data
contains an id/primary key
it'll be updated otherwise insert will be performed. In other words, for updating, you need to pass the id/primary key
in the $data/attributes
with other attributes and second argument in the newInstance
method must be true
.
如果$data
包含一个,id/primary key
它将被更新,否则将执行插入。换句话说,用于更新,你需要通过id/primary key
在$data/attributes
与其他属性,并在第二个参数newInstance
的方法必须是true
。
If you pass false/default
to newInstance
method then it'll perform an insert but $data
can't contain an id/primary
key. You got the idea and these three lines of code should work. $isSaved
will be a Boolean
value, true/false
.
如果您传递false/default
给newInstance
方法,那么它将执行插入但$data
不能包含id/primary
键。你明白了,这三行代码应该可以工作。$isSaved
将是一个Boolean
值,true/false
。
You may write the code using one line:
您可以使用一行编写代码:
with(new Feature)->newInstance($data, array_key_exists('id', $data))->save();
If $data
contains id/primary key
then it'll be updated, otherwise an insert will be performed.
如果$data
包含,id/primary key
那么它将被更新,否则将执行插入。