使用Laravel表单将同一数据集存入关联的独立数据表
Laravel双表(User+Profile)表单提交与关联实现
1. 建立模型关联
先确保User和Profile模型的关联关系配置正确:
- User模型(
app/Models/User.php):一个用户对应一份资料,使用hasOne关联
namespace App\Models; use Illuminate\Foundation\Auth\User as Authenticatable; class User extends Authenticatable { protected $fillable = ['name', 'username', 'password']; public function profile() { return $this->hasOne(Profile::class); } }
- Profile模型(
app/Models/Profile.php):资料属于某个用户,使用belongsTo关联
namespace App\Models; use Illuminate\Database\Eloquent\Model; class Profile extends Model { protected $fillable = ['address', 'phone_number']; public function user() { return $this->belongsTo(User::class); } }
数据库迁移说明
profiles表必须包含user_id外键字段,关联users表的id。如果未建表,参考以下迁移代码:
- users表迁移(调整默认字段):
Schema::create('users', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('username')->unique(); $table->string('password'); $table->timestamps(); });
- profiles表迁移:
Schema::create('profiles', function (Blueprint $table) { $table->id(); $table->foreignId('user_id')->constrained()->onDelete('cascade'); $table->text('address'); $table->string('phone_number'); $table->timestamps(); });
执行迁移:php artisan migrate
2. 创建表单视图
在resources/views下新建register.blade.php,包含双表所有字段:
<form method="POST" action="{{ route('register.store') }}"> @csrf <!-- 用户基础信息 --> <div> <label>姓名</label> <input type="text" name="name" value="{{ old('name') }}" required> @error('name') <span>{{ $message }}</span> @enderror </div> <div> <label>用户名</label> <input type="text" name="username" value="{{ old('username') }}" required> @error('username') <span>{{ $message }}</span> @enderror </div> <div> <label>密码</label> <input type="password" name="password" required> @error('password') <span>{{ $message }}</span> @enderror </div> <!-- 用户资料信息 --> <div> <label>地址</label> <textarea name="address" required>{{ old('address') }}</textarea> @error('address') <span>{{ $message }}</span> @enderror </div> <div> <label>手机号</label> <input type="text" name="phone_number" value="{{ old('phone_number') }}" required> @error('phone_number') <span>{{ $message }}</span> @enderror </div> <button type="submit">提交注册</button> </form>
3. 控制器处理表单提交
新建RegisterController处理表单显示与提交逻辑:
namespace App\Http\Controllers; use App\Models\User; use Illuminate\Http\Request; use Illuminate\Support\Facades\Hash; class RegisterController extends Controller { // 显示注册表单 public function create() { return view('register'); } // 处理表单提交 public function store(Request $request) { // 验证表单数据 $validated = $request->validate([ 'name' => 'required|string|max:255', 'username' => 'required|string|max:255|unique:users', 'password' => 'required|string|min:8', 'address' => 'required|text', 'phone_number' => 'required|string|max:20', ]); // 创建用户(密码加密存储) $user = User::create([ 'name' => $validated['name'], 'username' => $validated['username'], 'password' => Hash::make($validated['password']), ]); // 通过用户关联创建对应资料 $user->profile()->create([ 'address' => $validated['address'], 'phone_number' => $validated['phone_number'], ]); // 注册成功跳转 return redirect()->route('home')->with('success', '注册完成'); } }
4. 配置路由
在routes/web.php中添加路由:
use App\Http\Controllers\RegisterController; Route::get('/register', [RegisterController::class, 'create'])->name('register'); Route::post('/register', [RegisterController::class, 'store'])->name('register.store');
5. 关联数据调用示例
后续需要获取用户关联资料时,直接通过模型关联方法:
// 获取单个用户的资料 $user = User::find(1); $userAddress = $user->profile->address; $userPhone = $user->profile->phone_number; // 预加载关联数据,避免N+1查询问题 $users = User::with('profile')->get(); foreach ($users as $user) { echo "{$user->name} 的地址:{$user->profile->address}"; }
内容的提问来源于stack exchange,提问作者Werachai Tamboon
相关产品推荐
相关产品推荐

