如何使用单一表单(Laravel)在 2 个表中插入记录?

Posted

技术标签:

【中文标题】如何使用单一表单(Laravel)在 2 个表中插入记录?【英文标题】:How to insert record in 2 tables using single form (Laravel)? 【发布时间】:2021-11-25 15:59:10 【问题描述】:

控制器

public function store_resto(Request $request)
        // dd($request->all());
        $restaurant = new Restaurant();
        $restaurant->name = $request->input('name');
        $restaurant->email = $request->input('email');
        $restaurant->address = $request->input('address');
        $restaurant->save();
        $image = $request->hasfile('image');
            $photo = rand(1,9999).'.'.$image;
            $path = public_path().'/files/';
            $image->move($path, $photo);
                 RestoImage::create([
                     'image'=>$image,
                     'resto_id'=>$restaurant->id,
                      ]);

        $request->session()->flash('status', 'Restaurant added successfully');  
        return redirect('list');
    

查看文件

<form method="post" action="route('store_resto')" enctype="multipart/form-data">
@csrf
<div class="form-group">
    <label>Resto Name</label>
    <input type="name" name="name" class="form-control">
</div>
<div class="form-group">
    <label>Email</label>
    <input type="email" name="email" class="form-control">
  </div>
  <div class="form-group">
    <label>Address</label>
    <input type="text" name="address" class="form-control">
  </div>
  <div class="form-group">
    <label>Image</label>
    <input type="file" name="image" class="form-control">
  </div><br>
  <button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>

RestoImage 模型

class RestoImage extends Model

    
    use HasFactory;
    protected $fillable = ['image','resto_id'];
    public function restaurants()
        $this->belongsTo(Restaurant::class, 'resto_id');
    


餐厅模型

class Restaurant extends Model

    use HasFactory;
    public $timestamps = false;

    public function menus()
        $this->hasMany(Menu::class);
    
    public function restoimage()
        $this->hasOne(RestoImage::class, 'resto_id');
    

每家餐厅将有 1 张图片。当管理员提交表单时,应在两个表中插入 1 条记录,即餐厅和 resto_images。我尝试过这种方式,但是当我提交表单时,它显示错误“调用 bool 上的成员函数 move()”。如果我做错了,请纠正我。提前致谢。

【问题讨论】:

【参考方案1】:

在这里,我编写了您的代码来解释这些事情是如何工作的。这是一个可以帮助您的示例。不是两个,您可以从控制器的一个功能中添加这么多表。如果您找到解决方案或出现错误的原因,请批准我的回答。

您有错误,因为代码找不到您或我的图像格式:type(png, jpeg)

$photo = rand(1,9999).'.'.$image;

解决方案-您必须通过此代码获取图像格式或扩展名

$extention          = $emp_image_file->getClientOriginalExtension();

你的解决方案应该是这样的

  $path1 = 'assets/img/emp/'; 
              $destinationPath1    = $path1;
              $photo_file         = $request->file('image');
              $photo='';
              if($photo_file)
                $file_size = $photo_file->getSize();
                    
                    $image_name         = $photo_file->getClientOriginalName();

                    $extention          = $photo_file->getClientOriginalExtension();

                    $photo = value(function() use ($photo_file)
                    $filename = time().'.'. $photo_file->getClientOriginalExtension();
                    return strtolower($filename);
                    );
                    $photo_file->move($destinationPath1, $photo);

                  
                

将 js 放入视图文件中

<script type="text/javascript">


  function readURL(input) 
  if (input.image && input.image[0]) 
    var reader = new FileReader();
    
    reader.onload = function(e) 
      $('#imagePreview').attr('src', e.target.result);
    
    
    reader.readAsDataURL(input.files[0]);
  

</script>

这是你输入的

<input type="file" class="form-control" name="image"  >

我也曾为其他访客工作过一次


public function store_resto(Request $request)

       <!-- validation code begins -->
        $this->validate($request, [
            'name'=>'required|max:120',
            'email'=>'required|email|unique:users',
            
        ]);
        <!-- validation code ends -->

 $data = $request->all(); 

        $table1 =  Required_Model1::create([
       
        'name'     =>$data['emp_name'],
        'email'    =>$data['email'],
             
        ]);

        $table2 =  Required_Model2::create([
        

        'name'                 => $data['emp_name'],
        'code'                 => $data['emp_code'],
        'status'               => $data['emp_status'],
        'email'               => $data['email'],
        'gender'               => $data['gender'],
        

        'table1_id'              => $table1->id,
        ]);

        $table3 =  Required_Model3::create([
      
        'role' => $data['role'],
        'table1_id' => $table1->id,
        'table2_id' => $table2->id,


          if(isset($table1,  $table2, $table3)) 
            $request->session()->flash('status', 'Restaurant added successfully');
              return redirect()->route('employee-manager');
              else
                  return redirect()->back();
              

        
    

如果您不想验证或强制执行,请评论或删除这部分代码。

$this->validate($request, [
        'name'=>'required|max:120',
        'email'=>'required,
        
    ]);

以上代码说明

    列名必须填写120个字符或不能为空。 必须填写列电子邮件。 如果这两个不满足,它将重定向回来。

以下代码 如果像上面的代码一样设置验证,这将按照定义进行检查和工作。如果设置了验证,他们会检查两个字段名称和电子邮件,如果他们填写或不为空,它将继续进行。如果设置了验证字段未填充或空白,它们将重定向回来。如果没有设置验证,它将继续进行。

if(isset($table1,  $table2, $table3)) 
        $request->session()->flash('status', 'Restaurant added successfully');
          return redirect()->route('employee-manager');
          else
              return redirect()->back();
          

改变这两行

<input type="name" name="name" class="form-control" required="true" />
 <input type="email" name="email" class="form-control" required="true" />

Model 1应该是这样的

class Required_Model1 extends Model
   
    
    
    protected $fillable = ['name','email'];
   

  

Model 2应该是这样的

class Required_Model2 extends Model
   
    
    
    protected $fillable = ['name','code', 'status', 'email', 'gender', 'table1_id'];
   

  

Model 3应该是这样的

class Required_Model3 extends Model
   
    
   
    protected $fillable = ['role','table1_id', 'table2_id'];
   

  

让我们谈谈您发布时的错误 您遇到错误,因为您想以布尔形式移动图像名称。这里给你一个标准代码,你可以使用它

$path1 = 'assets/img/emp/'; 
              $destinationPath1    = $path1;
              $emp_image_file         = $request->file('employee_images');
              $emp_image='';
              if($emp_image_file)
                $file_size = $emp_image_file->getSize();
                    
                    $image_name         = $emp_image_file->getClientOriginalName();
                    $extention          = $emp_image_file->getClientOriginalExtension();
                    $emp_image = value(function() use ($emp_image_file)
                    $filename = time().'.'. $emp_image_file->getClientOriginalExtension();
                    return strtolower($filename);
                    );
                    $emp_image_file->move($destinationPath1, $emp_image);

                  
                

把它放在你想保存的表中

 'photo'                => $emp_image,

在您的视图中添加此内容,确保您按照您的要求进行编辑

<script type="text/javascript">


  function readURL(input) 
  if (input.employee_images && input.employee_images[0]) 
    var reader = new FileReader();
    
    reader.onload = function(e) 
      $('#employee_imagesPreview').attr('src', e.target.result);
    
    
    reader.readAsDataURL(input.files[0]);
  

</script>

这是输入

<input type="file" class="form-control" name="employee_images"  >

【讨论】:

【参考方案2】:
$image = $request->hasfile('image');

这个方法是一个布尔方法。它将返回真/假。而是使用

$request->file('image');

【讨论】:

【参考方案3】:

首先,这里:

$image = $request->hasfile('image');

您正在通过检查 $image 是否具有该文件来将其设置为布尔值,然后您想在该布尔值上运行移动,这是不可能的。宁可这样做:

if($request->hasfile('image'))

   $image = $request->file('image');
   $image->move($path, $photo);

【讨论】:

以上是关于如何使用单一表单(Laravel)在 2 个表中插入记录?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Laravel 中将数据从 1 个视图插入到 2 个表中

如何使用 laravel 集合获取最后插入的 ID 并将其插入到第二个表中?

Laravel:如何从具有关系的 3 个表中获取数据

从3个表中检索数据如何使用Laravel中的第一个表从最后一个表中检索数据

Laravel 连接 2 个表,第一个表中的一个数据和第二个表中的多行

将数据保存到 2 个表中 cakephp 3