正在尝试为特定产品ID laravel-8创建项目

2022-03-27 00:00:00 php laravel laravel-8
  1. 用户拥有多个产品且产品具有自己的ID 2)和A产品有很多项目 我无法使ProjectController 注:如果您需要更多详细信息,可以询问。 这是我的用户模型user.php
public function Products(){
        return $this->hasMany('AppModelsProduct');

    }

    public function Project(){
        return $this->hasMany('AppModelsProject');
    }

这是我的产品型号产品。php

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

    public function Project(){
        return $this->hasMany('AppModelsProject');
    }

这是我的项目模型项目。php

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

    public function Product(){
        return $this->belongsTo(Product::class);
    }
此处产品表将user_id作为forignId,而project表将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 IlluminateHttpResponse
     */
    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 IlluminateHttpResponse
     */
    public function create()
    {
        return view('projects.create');
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  IlluminateHttpRequest  $request
     * @return IlluminateHttpResponse
     */
    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  AppModelsProject  $project
     * @return IlluminateHttpResponse
     */
    public function show(Project $project)
    {
        // $category = $project->category;
        return view('projects.show', compact('project'));
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  AppModelsProject  $project
     * @return IlluminateHttpResponse
     */
    public function edit(Project $project)
    {
        return view('projects.edit', compact('project'));
    }
    /**
     * Update the specified resource in storage.
     *
     * @param  IlluminateHttpRequest  $request
     * @param  AppModelsProject  $project
     * @return IlluminateHttpResponse
     */
    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  AppModelsProject  $project
     * @return IlluminateHttpResponse
     */
    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表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();
        });

感谢您的帮助


解决方案

下面是您出错的两个可能原因。

  1. 上传的文件request()->file('file')包含标题名称为id的列。
如果是这种情况,您可能希望在导入过程中执行某种标头验证。即:

<?php

namespace AppImports;

use AppModelsProject;
use IlluminateSupportCollection;
use MaatwebsiteExcelConcernsToCollection;
use MaatwebsiteExcelConcernsImportable;
use MaatwebsiteExcelConcernsWithHeadingRow;

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 AppModelsProject;
use MaatwebsiteExcelConcernsToModel;
use MaatwebsiteExcelConcernsWithHeadingRow;

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

附录

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

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

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

Laravel Excel | Row Validation without ToModel

<?php

namespace AppImports;

use AppModelsProject;
use IlluminateSupportCollection;
use IlluminateSupportFacadesValidator;
use MaatwebsiteExcelConcernsToCollection;
use MaatwebsiteExcelConcernsImportable;
use MaatwebsiteExcelConcernsWithHeadingRow;

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 AppImports;

use AppModelsProject;
use AppModelsProduct;
use IlluminateSupportCollection;
use IlluminateSupportFacadesValidator;
use MaatwebsiteExcelConcernsToCollection;
use MaatwebsiteExcelConcernsImportable;
use MaatwebsiteExcelConcernsWithHeadingRow;
use MaatwebsiteExcelConcernsWithMapping;

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);
    }
   // ...

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

相关文章