简体   繁体   English

根据关系Laravel 5.8和Eloquent更新数据库表

[英]Updating DB tables based on relationships Laravel 5.8 and Eloquent

I have a problem with updating tables that belongTo another table. 我在更新属于另一个表的表时遇到问题。 I have a users table and a recipes table. 我有一个用户表和一个食谱表。 The Recipe model belongsTo the User model and the User model hasMany Recipe. 配方模型属于用户模型,而用户模型具有许多配方。

Each recipe is shown in my index view as a small card and on that card, as well as on each individual show page, I am printing recipe->author. 每个食谱在我的索引视图中显示为一张小卡片,在该卡片以及每个单独的显示页面上,我正在打印食谱->作者。 When a recipe is created, it takes the username attribute from the users table and sets this as the author attribute on the recipes table. 创建食谱时,它将从用户表中获取用户名属性,并将其设置为食谱表中的作者属性。 However, when I update the username of a user, the author attribute in the recipes table does not update accordingly. 但是,当我更新用户的用户名时,配方表中的author属性不会相应地更新。

User Model 用户模型

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

Recipe Model 配方模型

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

Can I possible add some logic in my UserController to account for this when I update a user? 更新用户时,是否可以在UserController中添加一些逻辑以解决此问题?

UserController@update 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]);
    }

I have read the Laravel docs and can't find anything that will quite do what I am looking for. 我已经阅读过Laravel文档,找不到任何可以完全满足我所寻找的东西。 Would appreciate any guidance! 希望得到任何指导!

You mean you store username in users , and you want to store the exact username in the author of recipes ? 您的意思是您将username存储在users ,并且想要将确切的username存储在recipesauthor中?

Why not you just reference the name using relationship $recipe->user->username . 为什么不使用$recipe->user->username关系引用名称。 It would query your users table based on your user_id in your recipes and get that username for you. 它将根据recipesuser_id查询users表,并为您获取该username

So that you're not storing duplicating data in your database. 这样就不会在数据库中存储重复数据。 There should be only one Single Source of Truth . 只有单一的真理来源 You can get your user data based on your user_id , there's no point to store another set of data and keep updating it when the source is changed. 您可以根据user_id获取用户数据,没有必要存储另一组数据并在源发生更改时继续更新。

If you find querying whole User model a bit of heavy, then you can use Recipe::with('users:id,username')->get() to query only the username . 如果发现查询整个User模型比较繁琐,则可以使用Recipe::with('users:id,username')->get()仅查询username

Or 要么

If you want to maintain the current $recipe->author , you can: 如果要保持当前的$recipe->author ,可以:

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

If you set up the foreign keys on your migration files, you may add the ->onUpdate('CASCADE') clause to the username foreign on the recipes table migration. 如果在迁移文件上设置了外键,则可以将->onUpdate('CASCADE')子句添加到recipes表迁移上的外来用户名中

Note: the onCascade foreign constraint would work outside of Laravel too, as it relies only on the database engine's support for foreign keys. 注意: onCascade外来约束也可以在Laravel之外使用,因为它仅依赖于数据库引擎对外键的支持。

Anyways, be careful with your validation as you have to be sure the new chosen username isn't already used by someone else. 无论如何,请务必谨慎确认,因为您必须确保新选择的用户名尚未被其他人使用。

Assuming your User model is connected to the users table and has an id primary key, make sure that you set the username column as unique in the database, and **validate* user input accordingly. 假设您的User模型已连接到users表并具有一个id主键,请确保您将用户名列设置为数据库中唯一的,并相应地“验证”用户输入。

The former is done by editing once again your migration. 前者是通过再次编辑迁移来完成的。

The latter is solved by modifying your rules like these ones: 可以通过修改以下规则来解决后者:

// 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)
    ]
]);

Note: if you modify migrations you have to rerun them in order to apply the modification. 注意:如果您修改迁移,则必须重新运行它们才能应用修改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM