【问题标题】:Updating DB tables based on relationships Laravel 5.8 and Eloquent基于关系 Laravel 5.8 和 Eloquent 更新数据库表
【发布时间】:2019-04-05 23:05:01
【问题描述】:

我在更新属于另一个表的表时遇到问题。 我有一个用户表和一个食谱表。 Recipe 模型属于 User 模型,并且 User 模型有很多 Recipe。

每个食谱在我的索引视图中显示为一张小卡片,在该卡片以及每个单独的显示页面上,我正在打印食谱->作者。创建配方时,它会从用户表中获取用户名属性并将其设置为配方表上的作者属性。但是,当我更新用户的用户名时,食谱表中的作者属性不会相应更新。

用户模型

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

配方模型

 public function user(){
        return $this->belongsTo('App\User');
    }

当我更新用户时,我可以在我的 UserController 中添加一些逻辑来解决这个问题吗?

用户控制器@更新

$user = Auth::user();

        $this->validate(request(), [
            'name' => 'required',
            'username' => 'required',
        ]);

          // Handle File Upload 
          if(request()->hasfile('profile_pic')){
            // Get filename with extension
            $fileameWithExt = request()->file('profile_pic')->getClientOriginalName();
            // Get just filename
            $filename = pathinfo($fileameWithExt, PATHINFO_FILENAME);
            // Get just extension
            $extension = request()->file('profile_pic')->getClientOriginalExtension();
            // Filename to store
            $fileNameToStore = $filename . '_' . time() . '.' . $extension;
            // Upload Image
            $path = request()->file('profile_pic')->storeAs('public/profile_pictures', $fileNameToStore);
        } else {
            $fileNameToStore = 'noimage.jpg';
        }

        $user->name = request('name');
        $user->username = request('username');
        $user->description = request('description');
        $user->location = request('location');
        if(request()->hasFile('profile_pic')){
            $user->profile_pic = $fileNameToStore;
        }
        $user->push();

        $user_id = Auth::user()->id;
        return redirect()->route('user', ['id' => $user_id]);
    }

我已阅读 Laravel 文档,但找不到任何可以完全满足我要求的内容。将不胜感激任何指导!

【问题讨论】:

    标签: php laravel eloquent


    【解决方案1】:

    您的意思是您将username 存储在users 中,并且您想将确切的username 存储在authorrecipes 中?

    为什么不直接使用关系$recipe->user->username 来引用名称。它会根据您的recipes 中的user_id 查询您的users 表,并为您获取username

    这样您就不会在数据库中存储重复的数据。应该只有一个Single Source of Truth。您可以根据您的user_id 获取您的用户数据,没有必要存储另一组数据并在源更改时不断更新。

    如果您发现查询整个User 模型有点繁重,那么您可以使用Recipe::with('users:id,username')->get() 只查询username

    或者

    如果你想保持当前的$recipe->author,你可以:

    // Recipe class
    public function getAuthorAttribute() {
      return $this->user->username;
    }
    

    【讨论】:

    • 嘿,谢谢你的回答。这正是我所需要的。你是完全正确的,我应该只用 $recipe->user->username 引用它并删除作者列。另外,感谢《单一真理来源》一文。适合每个人在构建数据库的早期阅读。
    【解决方案2】:

    如果您在迁移文件上设置了外键,您可以将->onUpdate('CASCADE') 子句添加到recipes 表迁移的用户名外部

    注意: onCascade 外约束也可以在 Laravel 之外工作,因为它只依赖于数据库引擎对外键的支持。

    无论如何,请小心您的验证,因为您必须确保新选择的用户名尚未被其他人使用。

    假设您的 User 模型连接到 users 表并具有 id 主键,请确保在数据库,并相应地**验证*用户输入。

    前者是通过再次编辑您的迁移来完成的。

    后者可以通过修改如下规则来解决:

    // Do not forget the Rule import at the top of your controller
    use Illuminate\Validation\Rule;
    
    // Then in your method
    $this->validate(request(), [
        'name' => 'required',
        'username' => [
            'required',
            Rule::unique('users', 'username')->ignore($user)
        ]
    ]);
    

    注意:如果您修改迁移,则必须重新运行它们才能应用修改。

    【讨论】:

      猜你喜欢
      • 2023-03-28
      • 1970-01-01
      • 2016-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-29
      • 2020-01-18
      • 2017-02-09
      相关资源
      最近更新 更多