我在Laravel项目中通过php artisan make:auth命令生成了注册表。我想通过添加一些功能来对它进行自定义,以便用户在注册时可以选择自己的性别。我制作了性别表,该表具有带有两个值“男人”和“女人”的“性别”列,还添加了带有“ gender_id”和“ user_id”列的“ gender_user”表。我建立了很多对很多关系,但是当我尝试注册用户时,出现错误消息
Method Illuminate\Database\Eloquent\Collection::genders does not exist.
它在user表中写入用户,但在sex_user表中不写入任何内容。我的关系经过测试,当我尝试从另一个控制者那里获取具有性别关系的用户时,它可以正常工作。任何帮助表示赞赏。这是我的代码。
RegisterController.php
<?php
namespace App\Http\Controllers\Auth;
use App\User;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Foundation\Auth\RegistersUsers;
class RegisterController extends Controller
{
/*
|--------------------------------------------------------------------------
| Register Controller
|--------------------------------------------------------------------------
|
| This controller handles the registration of new users as well as their
| validation and creation. By default this controller uses a trait to
| provide this functionality without requiring any additional code.
|
*/
use RegistersUsers;
protected $redirectTo = '/home';
public function __construct()
{
$this->middleware('guest');
}
protected function validator(array $data)
{
return Validator::make($data, [
'genders' => ['required', 'string', 'max:255'],
/* 'gender_id' => 'required|exists:mysql.genders,id',
'user_id' => 'required|exists:mysql.users,id', */
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'age' => ['required', 'integer', 'min:18'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
]);
}
protected function create(array $data)
{
$genders = DB::table('genders')
->whereIn(
'genders',
[
request()->genders
]
)
->pluck('id')
->toArray();
//dd($genders);
$user = User::create([
//'genders' => $data['genders'],
'name' => $data['name'],
'email' => $data['email'],
'age' => $data['age'],
'password' => Hash::make($data['password']),
]);
//dd($user);
$newUser = User::find($user);
$newUser->genders()->attach($genders);
dd($newUser);
return User::find($user);
}
}
User.php
<?php
namespace App;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name', 'email', 'password', 'age',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function genders()
{
return $this->belongsToMany(Gender::class, 'gender_user', 'user_id', 'gender_id');
}
public function userProfile()
{
return $this->hasOne(UserProfile::class);
}
public function photos()
{
return $this->hasMany(Photo::class, 'user_id', 'id');
}
}
Gender.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Gender extends Model
{
public function users()
{
return $this->belongsToMany(User::class, 'gender_user', 'gender_id', 'user_id');
}
}
gender_user表
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateGenderUserTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('gender_user', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('gender_id')->nullable();
$table->foreign('gender_id')->references('id')
->on('genders')->onDelete('cascade');
$table->unsignedBigInteger('user_id')->nullable();
$table->foreign('user_id')->references('id')
->on('users')->onDelete('cascade');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('gender_user');
}
}
性别表
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateGendersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('genders', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('genders');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('genders');
}
}
register.blade.php
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">{{ __('Register') }}</div>
<div class="card-body">
<form method="POST" action="{{ route('register') }}">
@csrf
<div class="form-group row">
<label for="genders" class="col-md-4 col-form-label text-md-right">{{ __('Genders') }}</label>
<div class="col-md-6">
<select id="genders" class="form-control @error('genders') is-invalid @enderror" name="genders" value="{{ old('genders') }}" required autocomplete="genders">
<option value="Woman">Woman</option>
<option value="Woman Looking For Woman">Woman Looking For Woman</option>
<option value="Man">Man</option>
</select>
@error('genders')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row">
<label for="name" class="col-md-4 col-form-label text-md-right">{{ __('Name') }}</label>
<div class="col-md-6">
<input id="name" type="text" class="form-control @error('name') is-invalid @enderror" name="name" value="{{ old('name') }}" required autocomplete="name" autofocus>
@error('name')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row">
<label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email">
@error('email')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row">
<label for="age" class="col-md-4 col-form-label text-md-right">{{ __('Age') }}</label>
<div class="col-md-6">
<select id="age" class="form-control @error('age') is-invalid @enderror" name="age" value="{{ old('age') }}" required autocomplete="age">
<option value="18">18</option>
<option value="19">19</option>
<option value="20">20</option>
<option value="21">21</option>
</select>
@error('age')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row">
<label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>
<div class="col-md-6">
<input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="new-password">
@error('password')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row">
<label for="password-confirm" class="col-md-4 col-form-label text-md-right">{{ __('Confirm Password') }}</label>
<div class="col-md-6">
<input id="password-confirm" type="password" class="form-control" name="password_confirmation" required autocomplete="new-password">
</div>
</div>
<div class="form-group row mb-0">
<div class="col-md-6 offset-md-4">
<button type="submit" class="btn btn-primary">
{{ __('Register') }}
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
答案 0 :(得分:1)
应您的要求,我正在为您答复。因此,首先从数据库表开始。
性别
Schema::create('genders', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('genders');
$table->timestamps();
$table->softDeletes();
});
用户
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->unsignedInteger('gender_id')->index();
//other attributes as per your need
$table->rememberToken();
$table->timestamps();
$table->softDeletes();
});
当某些父级被删除时,我正在使用软删除来确保安全,但是我仍然需要子行和该关系。
用户模型
<?php
namespace App;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\SoftDeletes;
class User extends Authenticatable
{
use Notifiable;
use SoftDeletes;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name', 'email', 'password', 'age', 'gender_id'
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
/**
* The attributes that should be mutated to dates.
*
* @var array
*/
protected $dates = ['deleted_at'];
public function gender()
{
return $this->belongsTo(Gender::class, 'gender_id')->withTrashed();
}
public function userProfile()
{
return $this->hasOne(UserProfile::class);
}
public function photos()
{
return $this->hasMany(Photo::class, 'user_id', 'id');
}
}
性别模型
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Gender extends Model
{
use SoftDeletes;
/**
* The attributes that should be mutated to dates.
*
* @var array
*/
protected $dates = ['deleted_at'];
//the relation is not necessary. but if you want how many users belongs
to a single gender you can determine from this relationship
public function users()
{
return $this->hasMany(User::class, 'gender_id');
}
}
注册表格
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">{{ __('Register') }}</div>
<div class="card-body">
<form method="POST" action="{{ route('register') }}">
@csrf
<div class="form-group row">
<label for="genders" class="col-md-4 col-form-label text-md-right">{{ __('Genders') }}</label>
<div class="col-md-6">
<select id="genders" class="form-control @error('genders') is-invalid @enderror" name="gender_id" value="{{ old('gender_id') }}" required autocomplete="genders">
<option value="">Select</option>
@forelse($genders as $gender)
<option value="{{ $gender->id }}"
@if( old('gender_id') == $gender->id )
selected
@endif>
{{ $gender->genders }}
</option>
@empty
<option value="">No Gender Found</option>
@endforelse
</select>
@error('genders')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row">
<label for="name" class="col-md-4 col-form-label text-md-right">{{ __('Name') }}</label>
<div class="col-md-6">
<input id="name" type="text" class="form-control @error('name') is-invalid @enderror" name="name" value="{{ old('name') }}" required autocomplete="name" autofocus>
@error('name')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row">
<label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email">
@error('email')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row">
<label for="age" class="col-md-4 col-form-label text-md-right">{{ __('Age') }}</label>
<div class="col-md-6">
<select id="age" class="form-control @error('age') is-invalid @enderror" name="age" value="{{ old('age') }}" required autocomplete="age">
<option value="18">18</option>
<option value="19">19</option>
<option value="20">20</option>
<option value="21">21</option>
</select>
@error('age')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row">
<label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>
<div class="col-md-6">
<input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="new-password">
@error('password')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row">
<label for="password-confirm" class="col-md-4 col-form-label text-md-right">{{ __('Confirm Password') }}</label>
<div class="col-md-6">
<input id="password-confirm" type="password" class="form-control" name="password_confirmation" required autocomplete="new-password">
</div>
</div>
<div class="form-group row mb-0">
<div class="col-md-6 offset-md-4">
<button type="submit" class="btn btn-primary">
{{ __('Register') }}
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
注册控制器
<?php
namespace App\Http\Controllers\Auth;
use App\User;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Validation\Rule;
class RegisterController extends Controller
{
/*
|--------------------------------------------------------------------------
| Register Controller
|--------------------------------------------------------------------------
|
| This controller handles the registration of new users as well as their
| validation and creation. By default this controller uses a trait to
| provide this functionality without requiring any additional code.
|
*/
use RegistersUsers;
protected $redirectTo = '/home';
public function __construct()
{
$this->middleware('guest');
}
protected function validator(array $data)
{
return Validator::make($data, [
'genders' => ['required', 'string', 'max:255'],
'gender_id' => ['required', Rule::notIn(['','0'])],
'user_id' => 'required|exists:mysql.users,id', */
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'age' => ['required', 'integer', 'min:18'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
]);
}
protected function create(array $data)
{
$user = User::create([
'name' => $data['name'],
'email' => $data['email'],
'gender_id' => $data['gender_id'],
'age' => $data['age'],
'password' => Hash::make($data['password']),
]);
return $user;
}
}
最后是RegistersUsers特征(vendor/laravel/framework/src/Illuminate/Foundation/Auth/RegistersUsers.php
)
<?php
namespace Illuminate\Foundation\Auth;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Auth\Events\Registered;
use App\Gender;
trait RegistersUsers
{
use RedirectsUsers;
/**
* Show the application registration form.
*
* @return \Illuminate\Http\Response
*/
public function showRegistrationForm()
{
$genders = Gender::all();
return view('auth.register',compact('genders');
}
/**
* Handle a registration request for the application.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function register(Request $request)
{
$this->validator($request->all())->validate();
event(new Registered($user = $this->create($request->all())));
$this->guard()->login($user);
return $this->registered($request, $user)
?: redirect($this->redirectPath());
}
/**
* Get the guard to be used during registration.
*
* @return \Illuminate\Contracts\Auth\StatefulGuard
*/
protected function guard()
{
return Auth::guard();
}
/**
* The user has been registered.
*
* @param \Illuminate\Http\Request $request
* @param mixed $user
* @return mixed
*/
protected function registered(Request $request, $user)
{
//
}
}
可以随意问任何您不了解的问题。快乐的编码:)
答案 1 :(得分:0)
将代码更改为
protected function create(array $data)
{
$genders = Gender::whereIn(
'genders',
[
request()->genders
]
)
->pluck('id')
->toArray();
$user = User::create([
'name' => $data['name'],
'email' => $data['email'],
'age' => $data['age'],
'password' => Hash::make($data['password']),
]);
$user->genders()->attach($genders);
return $user;
}
现在可以正常使用