【问题标题】:Trying to create project for specific product id laravel-8尝试为特定产品 ID laravel-8 创建项目
【发布时间】:2021-08-24 19:55:15
【问题描述】:
  1. 一个用户有很多产品并且产品有自己的ID 2)一个产品有很多项目 我无法制作 ProjectController 注意:如果您需要更多详细信息,可以询问。 这是我的用户模型 user.php
public function Products(){
        return $this->hasMany('App\Models\Product');

    }

    public function Project(){
        return $this->hasMany('App\Models\Project');
    }

这是我的产品模型 product.php

public function User(){
        return $this->belongsTo(User::class);
    }

    public function Project(){
        return $this->hasMany('App\Models\Project');
    }

这是我的项目模型project.php

public function User(){
        return $this->belongsTo(User::class);
    }

    public function Product(){
        return $this->belongsTo(Product::class);
    }

这里的产品表有 user_id 作为 forignId,项目表有 user_id 和 product_id 作为外键 这是项目表project.php

$table->unsignedBigInteger ('user_id');
            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
            $table->foreignId('product_id')->nullable();

这是我在ProjectController.php中遇到的麻烦

class ProjectController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        // $projects = Project::where('user_id',auth()->user()->id)->latest()->paginate(20);
        $projects = Project::where('user_id',auth()->user()->id)->where('product_id')->latest()->paginate(20);



        return view('projects.index', compact('projects'))
            ->with('i', (request()->input('page', 1) - 1) * 5);
    }

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

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request,$id)
    {
        $request->validate([
            'chapter_name' => 'required',
            'sub_section_name' => 'required',
            'title_1' => 'required',
            'description_1' => 'required',
            'image_1' => 'required',
            'image_2' => 'required',
            'image_3' => 'required',
            'title_2' => 'required',
            'description_2' => 'required',
            'title_3' => 'required',
            'description_3' => 'required',
            'video_1' => 'required',
            'video_2' => 'required',
            'video_3' => 'required',
        ]);

        // $input = $request->all();
        $input['user_id'] = auth()->user()->id;
        $input['product_id'] = $id;

        Project::create($input);

        return redirect()->route('project.index')
                        ->with('success','Product created successfully.');

    }

    /**
     * Display the specified resource.
     *
     * @param  \App\Models\Project  $project
     * @return \Illuminate\Http\Response
     */
    public function show(Project $project)
    {
        // $category = $project->category;
        return view('projects.show', compact('project'));
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  \App\Models\Project  $project
     * @return \Illuminate\Http\Response
     */
    public function edit(Project $project)
    {
        return view('projects.edit', compact('project'));
    }
    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Models\Project  $project
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, Project $project)
    {
        // $user_id =  Auth::user()->id ;

        $request->validate([
            'chapter_name' => 'required',
            'sub_section_name' => 'required',
            'title_1' => 'required',
            'description_1' => 'required',
            'image_1' => 'required',
            'image_2' => 'required',
            'image_3' => 'required',
            'title_2' => 'required',
            'description_2' => 'required',
            'title_3' => 'required',
            'description_3' => 'required',
            'video_1' => 'required',
            'video_2' => 'required',
            'video_3' => 'required',
        ]);

        $input = $request->all();

        $project->update($input);

        return redirect()->route('project.index')
                        ->with('success','Product updated successfully');
    }
    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\Models\Project  $project
     * @return \Illuminate\Http\Response
     */
    public function destroy(Project $project)
    {
        $project->delete();

        return redirect()->route('projects.index')
            ->with('success', 'Project deleted successfully');
    }

    public function importProject()
    {
        Excel::import(new ProjectsImport, request()->file('file'));

        return back()->with('success','Project created successfully.');
    }

    public function export()
    {
        return Excel::download(new UsersExport, 'projects.xlsx');
    }
}

这是用户表 user.php

 Schema::create('users', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->foreignId('current_team_id')->nullable();
            $table->text('profile_photo_path')->nullable();
            $table->timestamps();
        });

这是产品表 products.php

 Schema::create('products', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->text('detail');
            $table->string('color');
            $table->string('image');
            $table->string('logo');
            $table->unsignedBigInteger('user_id');
            $table->timestamps();
            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
        });

这是项目表project.php

Schema::create('projects', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('chapter_name', 255)->nullable();
            $table->string('sub_section_name', 500)->nullable();
            $table->string('title_1', 255)->nullable();
            $table->string('description_1', 5000)->nullable();
            $table->string('image_1', 255)->nullable();
            $table->string('image_2', 255)->nullable();
            $table->string('image_3', 255)->nullable();
            $table->string('title_2', 255)->nullable();
            $table->string('description_2', 5000)->nullable();
            $table->string('title_3', 255)->nullable();
            $table->string('description_3', 255)->nullable();
            $table->string('video_1', 255)->nullable();
            $table->string('video_2', 255)->nullable();
            $table->string('video_3', 255)->nullable();
            $table->unsignedBigInteger ('user_id');
            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
            // $table->foreignId('product_id')->nullable();
            $table->unsignedBigInteger('product_id')->references('id')->on('products')->onDelete('cascade');
            $table->timestamp('created_at')->useCurrent();
            $table->timestamp('updated_at')->nullable();
        });

感谢您的帮助

【问题讨论】:

  • 关系方法名不应该是get{Whatever},而应该是简单的{whatever},比如public function products()public function product(),而不是public function getProducts()public function getProduct()。这样,Laravel 可以根据你的模型自动链接它们。
  • 我不明白,对不起,我不是那么专家,我刚开始在 laravel
  • @AbdullahAlShahed ,什么不起作用?请具体一点。
  • @AbdullahAlShahed ,您说 “一个用户有很多产品”,然后继续在 UserProjects 之间建立联系UserProject 模型中。这是否意味着一个用户有很多产品和项目
  • 现在我的 projectImport.php 中有这个未定义的数组键“id”错误。看我的版本这个id应该是ptoduct id

标签: php laravel laravel-8


【解决方案1】:

以下是您的错误的 2 个可能原因。

  1. 上传的文件request()->file('file') 幸运的是标题名称为id 的列。

如果是这种情况,您可能希望在导入过程中执行某种标头验证。即:

<?php

namespace App\Imports;

use App\Models\Project;
use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\ToCollection;
use Maatwebsite\Excel\Concerns\Importable;
use Maatwebsite\Excel\Concerns\WithHeadingRow;

class ProjectsImport implements ToCollection, WithHeadingRow
{
    use Importable;

    private const HEADING_NAMES = [
        'chapter_name',
        'sub_section_name',
        'title_1',
        'description_1',
        'image_1',
        'image_2',
        'image_3',
        'title_2',
        'description_2',
        'title_3',
        'description_3',
        'video_1',
        'video_2',
        'video_3',
        'id'
    ];

    private const HEADING_ROW = 0;

    public function collection(Collection $rows)
    {

        if (
            (count($columnHeadings = array_keys($rows[self::HEADING_ROW])) == count(self::HEADING_NAMES))
            && (array_diff($columnHeadings, self::HEADING_NAMES) === array_diff(self::HEADING_NAMES, $columnHeadings))
        ) {
            redirect()
                ->back()
                ->withErrors([
                    "import" => "Incorrect excel sheet headers."
                        . " "
                        . "Expected:"
                        . " " . json_encode(self::HEADING_NAMES)
                ]);
        }

        // If validation fails, it won't reach the next statement.

        foreach ($rows as $row) {
            Project::create([
                'chapter_name' => $row['chapter_name'],
                // ...
            ]);
        }
    }

    public function headingRow(): int
    {
        return self::HEADING_ROW;
    }
}
  1. 您正在使用 标题名称 来访问数据,但默认情况下会使用 $row 索引。即:$row[0] 而不是 $row['chapter_name']

如果是这种情况,您可能希望实现 WithHeadingRow 关注点。

Laravel Excel | Heading Row

如果您的文件包含标题行(每个单元格包含 表示该列的用途)并且您想使用这些名称 作为每一行的数组键,您可以实现WithHeadingRow 担心。

即:

<?php
use App\Models\Project;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithHeadingRow;

class ProjectsImport implements ToModel, WithHeadingRow
{
    public function model(array $row)
    {
        return new Project([
            'chapter_name' => $row['chapter_name'],
            // ...
        ]);
    }
}

附录

如果上传的文件没有实际的'product_id's,而是有产品名称,您可以执行某种预处理以将产品名称替换为各自的'product_id's。

此外,您可以使用一些行验证来确保product names存在于数据库中。

A.验证产品名称,确保它们存在。

Laravel Excel | Row Validation without ToModel

<?php

namespace App\Imports;

use App\Models\Project;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Validator;
use Maatwebsite\Excel\Concerns\ToCollection;
use Maatwebsite\Excel\Concerns\Importable;
use Maatwebsite\Excel\Concerns\WithHeadingRow;

class ProjectsImport implements ToCollection, WithHeadingRow
{
    use Importable;

    public function collection(Collection $rows)
    {
        Validator::make($rows->toArray(), [
            // Table Name: 'products'. Table Column Name: 'name'. Excel Sheet Header Name: 'product_name'.
            '*.product_name' => ['required', 'exists:products,name'],
        ])->validate();

        // If validation fails, it won't reach the next statement.

        foreach ($rows as $row) {
            Project::create([

                'chapter_name' => $row['chapter_name'],
                // ...
            ]);
        }
    }
}

B. 执行某种预处理,将产品名称替换为各自的“product_id”

Laravel Excel | Mapping rows

通过添加WithMapping,您可以将需要添加的数据映射为 排。这样您就可以控制每列的​​实际来源。

即:

<?php

namespace App\Imports;

use App\Models\Project;
use App\Models\Product;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Validator;
use Maatwebsite\Excel\Concerns\ToCollection;
use Maatwebsite\Excel\Concerns\Importable;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\WithMapping;

class ProjectsImport implements ToCollection, WithHeadingRow, WithMapping
{
    use Importable;

    public function collection(Collection $rows)
    {

        Validator::make($rows->toArray(), [
            '*.chapter_name' => 'required',
            '*.sub_section_name' => 'required',
            '*.title_1' => 'required',
            '*.description_1' => 'required',
            '*.image_1' => 'required',
            '*.image_2' => 'required',
            '*.image_3' => 'required',
            '*.title_2' => 'required',
            '*.description_2' => 'required',
            '*.title_3' => 'required',
            '*.description_3' => 'required',
            '*.video_1' => 'required',
            '*.video_2' => 'required',
            '*.video_3' => 'required',
            '*.product_name' => ['required', 'exists:products,name'],
            '*.product_id' => ['required', 'numeric', 'exists:products,id'],
        ])->validate();

        foreach ($rows as $row) {
            Project::create([

                'chapter_name' => $row['chapter_name'],
                'product_id' => $row['product_id']
                // ...
            ]);
        }
    }

    public function map($row): array
    {
        $mappedRow = $row;

        $mappedRow['product_id'] = (isset($row['product_name'])
            && ($product = Product::firstWhere('name', $row['product_name'])))
            ? $product->id
            : null;

        return $mappedRow;

        // From this point, your rules() and model() functions can access the 'product_id'
    }
}

附录 2

看来index 方法中的第二个where 子句很幸运(ProjectController)。

    // ...
    public function index()
    {
        // $projects = Project::where('user_id',auth()->user()->id)->latest()->paginate(20);
        $projects = Project::where('user_id',auth()->user()->id)->where('product_id')->latest()->paginate(20); ❌

        return view('projects.index', compact('projects'))
            ->with('i', (request()->input('page', 1) - 1) * 5);
    }
   // ...

where 子句requires at least 2 parameters。为您的案例传递了一个 'product_id' 参数。

【讨论】:

  • SQLSTATE[23000]:完整性约束违规:1048 列“product_id”不能为空(SQL:插入projectschapter_namesub_section_nametitle_1description_1image_1image_2image_3title_2description_2title_3description_3video_1video_2video_3user_idproduct_idupdated_at, created_at) 值(第 1 章,sub 1,title 1,Desp 1,Img 1,img 2,img 3,Ti 2,Des 2,ti3,des 3,v1,vdo2,vdo3,1,?, 2021-06-08 10:19:01, 2021-06-08 10:19:01)) 这是错误现在我添加了最后一段代码
  • @AbdullahAlShahed ,这是因为您的 projects 表强制必须提供 product_id。检查我编辑的答案 (Edit 1 & Edit 2) 我刚刚添加了验证规则,以确保在任何字段为 null(空) 时在前端显示 validation error .
  • @AbdullahAlShahed,请注意,最后一个实现假定您有一个 Excel 工作表列,其 标题名称 名为 product_name
  • 感谢 ProjectImport.php 文件问题已解决,但是当我上传 excel 文件时,它在我的数据库中没有上传任何形式的 excel 文件。 ProjectController有问题吗
  • @AbdullahAlShahed,这很奇怪。由于我添加了 Importable trait ,您可以尝试使用它而不是使用 Excel::import(...) Facade。即:(new ProjectsImport)-&gt;import(request()-&gt;file('file')); 在您的 importProject 方法中?如果添加了新条目,请检查您的 projects 数据库表。
猜你喜欢
  • 2021-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-02
  • 1970-01-01
相关资源
最近更新 更多