我有一个settings
表格,用于存储网站标题,社交网络链接和其他内容...我可以通过设置缓存变量来完成所有操作。
现在,我的问题是,如何更新此表?例如......如果我有以下刀片形式:
{!! Form::model(config('settings'), ['class' => 's-form', 'route' => ['setting.update']]) !!}
{{ method_field('PUT') }}
<div class="s-form-item text">
<div class="item-title required">Nome do site</div>
{!! Form::text('title', null, ['placeholder' => 'Nome do site']) !!}
</div>
<div class="s-form-item text">
<div class="item-title required">Descrição do site</div>
{!! Form::text('desc', null, ['placeholder' => 'Descrição do site']) !!}
</div>
<div class="s-form-item s-btn-group s-btns-right">
<a href="{{ url('admin') }}" class="s-btn cancel">Voltar</a>
<input class="s-btn" type="submit" value="Atualizar">
</div>
{!! Form::close() !!}
在PUT
请求中,如何通过传递的每个名称在表中搜索并更新表?这是另一个文件:
路线
Route::put('/', ['as' => 'setting.update', 'uses' => 'Admin\AdminConfiguracoesController@update']);
控制器
class AdminConfiguracoesController extends AdminBaseController
{
private $repository;
public function __construct(SettingRepository $repository){
$this->repository = $repository;
}
public function geral()
{
return view('admin.pages.admin.configuracoes.geral.index');
}
public function social()
{
return view('admin.pages.admin.configuracoes.social.index');
}
public function analytics()
{
return view('admin.pages.admin.configuracoes.analytics.index');
}
public function update($id, Factory $cache, Setting $setting)
{
// Update?
$cache->forget('settings');
return redirect('admin');
}
}
存储库
class SettingRepository
{
private $model;
public function __construct(Setting $model)
{
$this->model = $model;
}
public function findByName($name){
return $this->model->where('name', $name);
}
}
模型
class Setting extends Model
{
protected $table = 'settings';
public $timestamps = false;
protected $fillable = ['value'];
}
的ServiceProvider
class SettingsServiceProvider extends ServiceProvider
{
public function boot(Factory $cache, Setting $settings)
{
$settings = $cache->remember('settings', 60, function() use ($settings)
{
return $settings->lists('value', 'name')->all();
});
config()->set('settings', $settings);
}
public function register()
{
//
}
}
移植
class CreateSettingsTable extends Migration
{
public function up()
{
Schema::create('settings', function (Blueprint $table) {
$table->increments('id');
$table->string('name', 100)->unique();
$table->text('value');
});
}
public function down()
{
Schema::drop('settings');
}
}
答案 0 :(得分:2)
好的,一步一步。
首先,让我们考虑一下我们真正想要实现的目标,并在第二步中看看实施情况。
查看代码,我假设您要创建一组未定义的视图,其中包含用于更新某些设置的表单。对于用户来说,设置似乎是按组进行结构化的,例如“常规”,“社交”,“分析”,但您不会像这样在数据库中构建您的设置。您的设置基本上是一个简单的键/值存储,与某些设置组没有任何关系。
更新时,您需要一种处理所有设置的单一更新方法,而不管发送更新请求的形式。
我希望我的假设是正确的,如果我不是,请纠正我。
好的很酷,但是,来吧,我该如何实现呢?
与往常一样,可能有一千种方法可以实现这样的东西。我已经编写了一个示例应用程序,以解释我将如何实现它,我认为它非常 Laravelish (简而言之!)。
<强> 1。我应该如何存储我的数据?
我们已经谈过了。我们想要一个在数据库中持久存在的基本键/值存储。因为我们与Laravel合作,让我们为此创建一个模型和迁移:
php artisan make:model Setting --migration
这将创建一个模型和适当的迁移。让我们编辑迁移以创建键/值列:
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateSettingsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('settings', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->text('value');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('settings');
}
}
在设置模型中,我们必须将name
列添加到可填充数组中。我将解释为什么我们需要在下面。基本上,我们想要使用一些不错的Laravel API,因此我们必须使name-attribute可填充。
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Setting extends Model {
/**
* @var array
*/
protected $fillable = ['name'];
}
<强> 2。我如何访问设置数据?
我们讨论了这个in your last question,所以我不会详细介绍这个,我假装这个代码已经存在。我将在此示例中使用存储库,因此我将在开发期间更新SettingsServiceProvider
。
第3。创建存储库
为了使依赖关系更加松散耦合,我将创建一个接口(Laravel世界中的契约)并将其绑定到具体实现。然后我可以使用带有依赖注入的契约,Laravel将使用Service Container自动解决具体实现。也许这对你的应用程序来说太过分了,但无论我的应用程序有多大,我都喜欢编写可测试的代码。
app/Repositories/SettingRepositoryInterface.php
:
<?php
namespace App\Repositories;
interface SettingRepositoryInterface {
/**
* Update a setting or a given set of settings.
*
* @param string|array $key
* @param string $value
*
* @return void
*/
public function update($key, $value);
/**
* List all available settings (name => value).
*
* @return array
*/
public function lists();
}
如您所见,我们将使用存储库更新设置并在键/值数组中列出我们的设置。
具体实现(在本例中为Eloquent)如下所示:
app/Repositories/EloquentSettingRepository.php
<?php
namespace App\Repositories;
use App\Setting;
class EloquentSettingRepository implements SettingRepositoryInterface {
/**
* @var \App\Setting
*/
private $settings;
/**
* EloquentSettingRepository constructor.
*
* @param \App\Setting $settings
*/
public function __construct(Setting $settings)
{
$this->settings = $settings;
}
/**
* Update a setting or a given set of settings.
* If the first parameter is an array, the second parameter will be ignored
* and the method calls itself recursively over each array item.
*
* @param string|array $key
* @param string $value
*
* @return void
*/
public function update($key, $value = null)
{
if (is_array($key))
{
foreach ($key as $name => $value)
{
$this->update($name, $value);
}
return;
}
$setting = $this->settings->firstOrNew(['name' => $key]);
$setting->value = $value;
$setting->save();
}
/**
* List all available settings (name => value).
*
* @return array
*/
public function lists()
{
return $this->settings->lists('value', 'name')->all();
}
}
DocBlocks几乎可以解释如何实现存储库。在更新方法中,我们使用firstOrNew
方法。这就是为什么我们必须更新模型中的可填充数组。
现在让我们将接口绑定到该实现。在app/Providers/SettingsServiceProvider.php
中,将其添加到register-method:
/**
* Register any application services.
*
* @return void
*/
public function register()
{
$this->app->bind(
\App\Repositories\SettingRepositoryInterface::class,
\App\Repositories\EloquentSettingRepository::class
);
}
我们可以将此添加到AppServiceProvider
,但由于我们的设置有专门的服务提供商,因此我们会将其用于绑定。
现在我们已经完成了存储库,我们可以更新SettingsServiceProvider
的boot-method中的现有代码,以便它使用存储库而不是硬编码App\Setting
。
/**
* Bootstrap the application services.
*
* @param \Illuminate\Contracts\Cache\Factory $cache
* @param \App\Repositories\SettingRepositoryInterface $settings
*/
public function boot(Factory $cache, SettingRepositoryInterface $settings)
{
$settings = $cache->remember('settings', 60, function() use ($settings)
{
return $settings->lists();
});
config()->set('settings', $settings);
}
<强> 4。路线和控制器
在这个简单的示例中,主页将显示一个表单来更新某些设置。在同一路由上发出PUT / PATCH请求将触发更新方法:
<?php
get('/', ['as' => 'settings.index', 'uses' => 'Admin\SettingsController@index']);
put('/', ['as' => 'settings.update', 'uses' => 'Admin\SettingsController@update']);
我们控制器的索引方法将返回包含表单的视图。我已经对整个更新方法进行了评论,以解释每一行的作用:
app/Http/Controllers/Admin/SettingsController.php
:
<?php
namespace App\Http\Controllers\Admin;
use Illuminate\Contracts\Cache\Factory;
use Illuminate\Http\Request;
use App\Repositories\SettingRepositoryInterface;
class SettingsController extends AdminBaseController {
/**
* @var \App\Repositories\SettingRepositoryInterface
*/
private $settings;
/**
* SettingsController constructor.
*
* @param \App\Repositories\SettingRepositoryInterface $settings
*/
public function __construct(SettingRepositoryInterface $settings)
{
$this->settings = $settings;
}
/**
* Shows the setting edit form.
*
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function index()
{
return view('settings.index');
}
/**
* Update the settings passed in the request.
*
* @param \Illuminate\Http\Request $request
* @param \Illuminate\Contracts\Cache\Factory $cache
*
* @return \Illuminate\Http\RedirectResponse
*/
public function update(Request $request, Factory $cache)
{
// This will get all settings as a key/value array from the request.
$settings = $request->except('_method', '_token');
// Call the update method on the repository.
$this->settings->update($settings);
// Clear the cache.
$cache->forget('settings');
// Redirect to some page.
return redirect()->route('settings.index')
->with('updated', true);
}
}
请注意update方法中的第一个语句。除了方法和CSRF令牌之外,它将从请求中获取所有POST数据。 $settings
现在是一个关联数组,其中包含您在表单中发送的设置。
<强> 5。最后,观点
对不起Bootstrap课程,但我想快速设置我的示例应用程序样式: - )
我认为HTML非常明显:
resources/views/settings/index.blade.php
:
@extends('layout')
@section('content')
<h1>Settings example</h1>
@if(Session::has('updated'))
<div class="alert alert-success">
Your settings have been updated!
</div>
@endif
<form action="{!! route('settings.update') !!}" method="post">
{!! method_field('put') !!}
{!! csrf_field() !!}
<div class="form-group">
<label for="title">Title</label>
<input type="text" class="form-control" id="title" name="title" placeholder="Title" value="{{ config('settings.title', 'Application Title') }}">
</div>
<div class="form-group">
<label for="Facebook">Facebook</label>
<input type="text" class="form-control" id="facebook" name="facebook" placeholder="Facebook URL" value="{{ config('settings.facebook', 'Facebook URL') }}">
</div>
<div class="form-group">
<label for="twitter">Twitter</label>
<input type="text" class="form-control" id="twitter" name="twitter" placeholder="Twitter URL" value="{{ config('settings.twitter', 'Twitter URL') }}">
</div>
<input type="submit" class="btn btn-primary" value="Update settings">
</form>
@stop
正如您所看到的,当我尝试从配置中获取值时,我也会给它一个默认值,以防它尚未设置。
您现在可以为不同的设置组创建不同的表单。表单操作应始终为settings.update
路径。
当我运行应用程序时,我可以看到具有默认值的表单:
当我输入一些值时,点击更新按钮,Laravel再次将我重定向到表单,我可以看到成功消息和我的设置现在仍然存在于数据库中。
答案 1 :(得分:0)
您可以注入Request
课程。让我们更新title
:
// Injecting Illuminate\Http\Request object
public function update(Request $request, $id, Factory $cache, Setting $setting)
{
$newTitle = $request->get('title');
$cache->forget('settings');
return redirect('admin');
}
要更改db中的值,可以执行以下操作:
$titleSetting = App\Setting::where('name', 'title')->first();
$titleSetting->value = $newTitle;
$titleSetting->save();
整个代码如下:
public function update(Request $request, $id)
{
$newTitle = $request->get('title');
\Cache::forget('settings');
$titleSetting = App\Setting::where('name', 'title')->first();
$titleSetting->value = $newTitle;
$titleSetting->save();
return redirect('admin');
}