Php 在Laravel 5.3中创建相关模型实例时出错

Php 在Laravel 5.3中创建相关模型实例时出错,php,mysql,orm,laravel-5.3,entity-relationship,Php,Mysql,Orm,Laravel 5.3,Entity Relationship,我刚刚开始一个基于Laravel的项目,但在创建与另一个项目相关的模型实例时遇到了问题。总之,我有一个引用“companys”MySQL表的“Company”模型类,还有一个引用“locations”表的“Location”模型类。这两个表都是相关的(一个公司有许多位置,每个位置都属于一个公司)。到目前为止还不错 我有一个“中间件”机制来检查是否存在至少一家公司,如果没有公司,我假设这是第一次运行系统,因此我显示“创建公司”控制器/操作,以便用户创建第一家公司。提交时,这也会使用完全相同的公司信

我刚刚开始一个基于Laravel的项目,但在创建与另一个项目相关的模型实例时遇到了问题。总之,我有一个引用“companys”MySQL表的“Company”模型类,还有一个引用“locations”表的“Location”模型类。这两个表都是相关的(一个公司有许多位置,每个位置都属于一个公司)。到目前为止还不错

我有一个“中间件”机制来检查是否存在至少一家公司,如果没有公司,我假设这是第一次运行系统,因此我显示“创建公司”控制器/操作,以便用户创建第一家公司。提交时,这也会使用完全相同的公司信息创建一个位置记录,因此,数据库中的位置记录最终应该将刚刚创建的公司记录的id作为“Company_id”,但这不会发生

让我显示与此问题相关的现有文件和类:

创建公司表的迁移文件:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateCompaniesTable extends Migration {
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up() {
        Schema::create('companies', function (Blueprint $table) {
            $table->increments('id');
            $table->string('nit');
            $table->string('name');
            $table->string('contact_name')->nullable();
            $table->string('address')->nullable();
            $table->string('phone')->nullable();
            $table->string('email')->nullable();
            $table->string('website')->nullable();
            $table->timestamps();
            $table->softDeletes();
            $table->integer('created_by')->unsigned()->nullable();
            $table->integer('updated_by')->unsigned()->nullable();
            $table->integer('deleted_by')->unsigned()->nullable();

            $table->foreign('created_by')->references('id')->on('users')
                ->onDelete('cascade');
            $table->foreign('updated_by')->references('id')->on('users')
                ->onDelete('cascade');
            $table->foreign('deleted_by')->references('id')->on('users')
                ->onDelete('cascade');

            $table->index('nit');
            $table->index('name');
            $table->index('created_at');
            $table->index('deleted_at');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down() {
        Schema::dropIfExists('companies');
    }
}
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateLocationsTable extends Migration {
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up() {
        Schema::create('locations', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('company_id')->unsigned()->nullable();
            $table->string('nit');
            $table->string('name');
            $table->string('contact_name')->nullable();
            $table->string('address')->nullable();
            $table->string('phone')->nullable();
            $table->string('email')->nullable();
            $table->string('website')->nullable();
            $table->timestamps();
            $table->softDeletes();
            $table->integer('created_by')->unsigned()->nullable();
            $table->integer('updated_by')->unsigned()->nullable();
            $table->integer('deleted_by')->unsigned()->nullable();

            $table->foreign('created_by')->references('id')->on('users')
                ->onDelete('cascade');
            $table->foreign('updated_by')->references('id')->on('users')
                ->onDelete('cascade');
            $table->foreign('deleted_by')->references('id')->on('users')
                ->onDelete('cascade');

            $table->foreign('company_id')->references('id')->on('companies')
                ->onDelete('cascade');

            $table->index('nit');
            $table->index('name');
            $table->index('created_at');
            $table->index('deleted_at');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down() {
        Schema::dropIfExists('locations');
    }
}
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

/**
 * App\Location
 */
class Location extends Model {
    use SoftDeletes;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'nit', 'name', 'contact_name', 'address', 'phone', 'email', 'website', 'company_id',
    ];

    /**
     * The attributes that should be mutated to dates.
     *
     * @var array
     */
    protected $dates = ['deleted_at'];

    /**
     * Get the company that owns the location.
     */
    public function company() {
        return $this->belongsTo(Company::class);
    }

    /**
     * Get the products for the location.
     */
    public function products() {
        return $this->hasMany(Product::class);
    }

    /**
     * Get the inventory records for the location.
     */
    public function inventories() {
        return $this->hasMany(Inventory::class);
    }

    /**
     * Get the user that created the record.
     */
    public function createdBy() {
        return $this->belongsTo(User::class, 'created_by');
    }

    /**
     * Get the last user that updated the record.
     */
    public function updatedBy() {
        return $this->belongsTo(User::class, 'updated_by');
    }

    /**
     * Get the user that removed the record.
     */
    public function deletedBy() {
        return $this->belongsTo(User::class, 'deleted_by');
    }
}
<?php

namespace App\Http\Middleware;

use App\Company;
use Closure;

class CheckSystemFirstRun {
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request $request
     * @param  \Closure                 $next
     * @return mixed
     */
    public function handle($request, Closure $next) {

        /** @var \Illuminate\Http\Response $response */
        $response = $next($request);

        // The verification must be done AFTER the response has been generated, otherwise the request's route is
        // unknown.
        if ($request->route()->getName() != 'company.create') {

            // Check if there are no active companies.
            if (Company::count() == 0) {
                return redirect(route('company.create'));
            }
        } else {

            // Check if there are active companies.
            if (Company::count() > 0) {
                return redirect(route('dashboard'));
            }
        }

        return $response;
    }
}
<?php

namespace App\Http\Controllers;

use App\Company;
use App\Http\Requests\AddCompanyRequest;
use Illuminate\Http\Request;

class CompanyController extends Controller {


    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create() {
        return view('company.create');
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param AddCompanyRequest $request
     * @param Company           $company
     * @return \Illuminate\Http\Response
     */
    public function store(AddCompanyRequest $request, Company $company) {
        $company->create($request->all());

        // If there are no locations, create one using the same data as the received to create the company.
        if ($company->locations->count() == 0) {
            $company->locations()->create($request->all());
        }

        return redirect()->route('company.create');
    }
}
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class AddCompanyRequest extends FormRequest {
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize() {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules() {
        return [
            'nit'     => 'required|max:255',
            'name'    => 'required|max:255',
            'email'   => 'required|email|unique:companies|max:255',
            'website' => 'url|max:255',
        ];
    }

}

两者都没有成功

我正在使用MySQL版本15.1发行版10.1.10-MariaDB,用于Windows10x64、PHP7.0.4上的Win32(AMD64)

非常感谢您的帮助。谢谢


更新01

以下是执行操作时执行的查询的输出:

----------------------
Query: insert into `companies` (`nit`, `name`, `contact_name`, `address`, `phone`, `email`, `website`, `updated_at`, `created_at`) values (?, ?, ?, ?, ?, ?, ?, ?, ?)
Bindings: array (
  0 => '1113332323-9',
  1 => 'TEST COMPANY INC',
  2 => 'JOHN DOE',
  3 => '1362 36TH PL',
  4 => '8889990099',
  5 => 'test@test.com',
  6 => 'http://test.com',
  7 => '2017-01-16 00:16:25',
  8 => '2017-01-16 00:16:25',
)
Time: 4.5099999999999998

----------------------
Query: select * from `locations` where `locations`.`company_id` is null and `locations`.`company_id` is not null and `locations`.`deleted_at` is null
Bindings: array (
)
Time: 0.48999999999999999

----------------------
Query: insert into `locations` (`nit`, `name`, `contact_name`, `address`, `phone`, `email`, `website`, `company_id`, `updated_at`, `created_at`) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Bindings: array (
  0 => '1113332323-9',
  1 => 'TEST COMPANY INC',
  2 => 'JOHN DOE',
  3 => '1362 36TH PL',
  4 => '8889990099',
  5 => 'test@test.com',
  6 => 'http://test.com',
  7 => NULL,
  8 => '2017-01-16 00:16:25',
  9 => '2017-01-16 00:16:25',
)
Time: 4.5300000000000002

您正在将位置添加到您的ORM实例中的
公司
,而不是新创建的记录

$company->create($request->all());
应该是

$company=$company->create($request->all());

除了一些不相关的改进之外,位置创建代码看起来不错(我在本地创建了一个最小的示例,并且
公司id
分配正确)。您可以检查您的查询日志并发布结果吗?另外,您不需要将FK列设置为可空(除非您有无公司位置的用例),因为
$company::locations()->create([])
应该指定正确的FK值。@nCrazed,请检查主要问题内容中的“Update 01”部分。我只是根据请求添加了日志输出。插入查询缺少公司id值。至于你对可撤销公司id的评论,我同意你的看法。如果我从迁移文件中删除nullable标志并刷新,上述过程将生成完整性冲突异常,因为插入的位置记录没有所需的公司id。这就是答案。我认为create/save方法将更新相同的$company实例,而无需将其结果分配给相同的$company变量。谢谢。
$company->locations()->create($request->all());
$location = new Location($request->all());
$company->locations()->save($location);
----------------------
Query: insert into `companies` (`nit`, `name`, `contact_name`, `address`, `phone`, `email`, `website`, `updated_at`, `created_at`) values (?, ?, ?, ?, ?, ?, ?, ?, ?)
Bindings: array (
  0 => '1113332323-9',
  1 => 'TEST COMPANY INC',
  2 => 'JOHN DOE',
  3 => '1362 36TH PL',
  4 => '8889990099',
  5 => 'test@test.com',
  6 => 'http://test.com',
  7 => '2017-01-16 00:16:25',
  8 => '2017-01-16 00:16:25',
)
Time: 4.5099999999999998

----------------------
Query: select * from `locations` where `locations`.`company_id` is null and `locations`.`company_id` is not null and `locations`.`deleted_at` is null
Bindings: array (
)
Time: 0.48999999999999999

----------------------
Query: insert into `locations` (`nit`, `name`, `contact_name`, `address`, `phone`, `email`, `website`, `company_id`, `updated_at`, `created_at`) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Bindings: array (
  0 => '1113332323-9',
  1 => 'TEST COMPANY INC',
  2 => 'JOHN DOE',
  3 => '1362 36TH PL',
  4 => '8889990099',
  5 => 'test@test.com',
  6 => 'http://test.com',
  7 => NULL,
  8 => '2017-01-16 00:16:25',
  9 => '2017-01-16 00:16:25',
)
Time: 4.5300000000000002