【发布时间】:2016-10-06 11:38:13
【问题描述】:
我正在编写基于提供的输入和现有数据插入、更新或删除表行的逻辑。
- 如果没有输入,并且该行存在,则应删除该行。
- 如果有输入,但该行不存在,则应该创建它。
- 最后,如果有输入且行存在,则应更新行。
该项目是attributes 表的测试代码,该表具有name、value 和media_id(它引用已被赋予属性的媒体片段)。 name 和media_id 一起是唯一的(一个媒体不能有两个同名的属性)。使用插入、更新和删除对项目很重要,而不是如果为空则将它们留空。
我的问题是是否有更简单的方法来执行此逻辑。我可以只将它用于一个输入,但是当有两个(name 和 description)并且我以后可能会添加更多时,它似乎需要使用大量代码。有没有更有效的方法?
我的数据库迁移:
Schema::create('attributes', function (Blueprint $table) {
$table->increments('id')->unsigned();
$table->integer('media_id')->unsigned();
$table->string('name');
$table->text('value')->nullable();
$table->timestamps();
$table->unique(['media_id', 'name']);
$table->foreign('media_id')->references('id')->on('media')->onDelete('cascade');
});
我的看法:
<form action="{{ Request::path() }}" method="post">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<label style="display:block" for="name">Name</label>
<input type="text" name="name" id="name" value="{{ $attributes->get('name') ? $attributes->get('name')->value : '' }}">
<label style="display:block" for="description">Description</label>
<textarea name="description" id="description">{{ $attributes->get('description') ? $attributes->get('description')->value : '' }}</textarea>
<button type="submit">Save</button>
</form>
我的临时控制器:
Route::post('/', function(Request $request) {
$media = Media::find(1);
$attributes = $media->attributes->keyBy('name');
if($request->input('name')) {
if($attributes->get('name')) {
$attributes->get('name')->value = $request->input('name');
if(!$attributes->get('name')->save()) {
return "error updating name";
}
} else {
$attribute = new Attribute;
$attribute->name = 'name';
$attribute->value = $request->input('name');
if(!$media->attributes()->save($attribute)) {
return "error inserting name";
}
}
} else {
if($attributes->get('name')) {
if(!$attributes->get('name')->delete()) {
return "error deleting name";
}
}
}
if($request->input('description')) {
if($attributes->get('description')) {
$attributes->get('description')->value = $request->input('description');
if(!$attributes->get('description')->save()) {
return "error updating description";
}
} else {
$attribute = new Attribute;
$attribute->name = 'description';
$attribute->value = $request->input('description');
if(!$media->attributes()->save($attribute)) {
return "error inserting description";
}
}
} else {
if($attributes->get('description')) {
if(!$attributes->get('description')->delete()) {
return "error deleting description";
}
}
}
});
return redirect('/');
(还有一个用于 GET 的控制器,它显示表单和数据库输出。我没有打扰它,因为我觉得没有必要。)
我死的简单模型:
class Attribute extends Model
{
public function media()
{
return $this->belongsTo('App\Media');
}
}
【问题讨论】:
-
有几件事,
if($request->input('name'))部分应该是if($request->has('name')),这将始终返回true或false。如果它返回false,您可以在桌子上运行delete。您可以使用attribute表上的firstOrNew方法通过搜索model和name来更新或插入attribute到表中。 -
为什么不使用 restful 路由和内置验证?
-
@KevinCompton 它正在以特定方式用于用户界面,但我正在考虑根据此处的信息实际重写它,然后使用 Angular 使用户界面运行。
-
@Furze Ahhh 我明白了。我推荐 Vuejs,比 Angular 干净得多。
-
@Furze,我使用 Angular 作为我所有项目的前端,并使用 Laravel 作为 API 框架。特别适用于速率限制和可用的 oAuth 包。
标签: php mysql laravel model eloquent