Skip to content

Commit

Permalink
Resourceful routing
Browse files Browse the repository at this point in the history
  • Loading branch information
inxilpro committed Apr 15, 2019
1 parent ebb4d63 commit 2ef6b54
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 0 deletions.
31 changes: 31 additions & 0 deletions src/Elements/Form.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@
use Galahad\Aire\Aire;
use Galahad\Aire\Elements\Concerns\CreatesElements;
use Galahad\Aire\Elements\Concerns\CreatesInputTypes;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Routing\Router;
use Illuminate\Routing\UrlGenerator;
use Illuminate\Session\Store;
use Illuminate\Support\HtmlString;
use Illuminate\Support\Str;
use Illuminate\Support\ViewErrorBag;

class Form extends \Galahad\Aire\DTD\Form
Expand Down Expand Up @@ -139,6 +141,35 @@ public function bind($bound_data) : self
return $this;
}

/**
* Bind data with implicit resource controller routing
*
* Form::resourceful(new User()) -> POST route('users.store')
* Form::resourceful($existing_user) -> PUT route('users.update')
*
* @param \Illuminate\Database\Eloquent\Model $model
* @param string $resource_name
* @return \Galahad\Aire\Elements\Form
*/
public function resourceful(Model $model, $resource_name = null) : self
{
$this->bind($model);

if (null === $resource_name) {
$resource_name = Str::kebab(Str::plural($model->getTable()));
}

if ($model->exists) {
$this->action($this->url->route("{$resource_name}.update", $model));
$this->put();
} else {
$this->action($this->url->route("{$resource_name}.store"));
$this->post();
}

return $this;
}

/**
* Determine whether the form has any bound data
*
Expand Down
61 changes: 61 additions & 0 deletions tests/Feature/ResourcefulBindingTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

/** @noinspection ReturnTypeCanBeDeclaredInspection */

namespace Galahad\Aire\Tests\Feature;

use Galahad\Aire\Tests\TestCase;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\URL;

class ResourcefulBindingTest extends TestCase
{
protected function setUp()
{
parent::setUp();

Route::post('/users', function() {})->name('users.store');
Route::put('/users/{user}', function() {})->name('users.update');
}

public function test_action_and_method_are_inferred_for_unsaved_models()
{
$model = new XResourcefulModel(['id' => 1]);

$html = $this->aire()->form()->resourceful($model)->render();

$this->assertSelectorAttribute($html, 'form', 'action', URL::to('/users'));
$this->assertSelectorAttribute($html, 'form', 'method', 'POST');
$this->assertSelectorDoesNotExist($html, 'input[name="_method"]');
}

public function test_action_and_method_are_inferred_for_saved_models()
{
$model = new XResourcefulModel(['id' => 1]);
$model->exists = true;

$html = $this->aire()->form()->resourceful($model)->render();

$this->assertSelectorAttribute($html, 'form', 'action', URL::to('/users/1'));
$this->assertSelectorAttribute($html, 'input[name="_method"]', 'value', 'PUT');
}

public function test_provided_name_overrides_inferred_name() : void
{
Route::post('/foo/bar', function() {})->name('foo.bar.store');

$model = new XResourcefulModel(['id' => 1]);

$html = $this->aire()->form()->resourceful($model, 'foo.bar')->render();

$this->assertSelectorAttribute($html, 'form', 'action', URL::to('/foo/bar'));
}
}

class XResourcefulModel extends Model
{
protected $guarded = [];

protected $table = 'users';
}

0 comments on commit 2ef6b54

Please sign in to comment.