laravel如何处理个人资料页面?

I am playing around with Laravel 5. I am trying to build a site where a user can add some information about himself and it shows up in the frontend.

I am struggling to understand how to save the profile information only once. Everytime the user call /profile/create a new DB entry is created. But I only need one profile entry per user! If I don't provide a /profile/create route how can a user save his profile info to the DB? As the user can't call profile/edit because no entry exists.

This is my Controller:

namespace App\Http\Controllers;



use App\User;
use App\Profile;
use App\Http\Requests\ProfileRequest;
use App\Http\Requests;
use Illuminate\Http\Request;
use Auth;

class ProfilesController extends Controller
{
/**
 * Display a listing of the resource.
 *
 * @return \Illuminate\Http\Response
 */
public function index()
{
  return view('backend.profile.index');
}

/**
 * Show the form for creating a new resource.
 *
 * @return \Illuminate\Http\Response
 */
public function create()
{
  return view('backend.profile.create');
}

/**
 * Store a newly created resource in storage.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return \Illuminate\Http\Response
 */
public function store(ProfileRequest $request)
{
    $profile = new Profile($request->all());
    Auth::user()->profiles()->save($profile);
    return 'saved';
}

/**
 * Display the specified resource.
 *
 * @param  int  $id
 * @return \Illuminate\Http\Response
 */
public function show($id)
{
    //
}

/**
 * Show the form for editing the specified resource.
 *
 * @param  int  $id
 * @return \Illuminate\Http\Response
 */
public function edit($id)
{
    //
}

/**
 * Update the specified resource in storage.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  int  $id
 * @return \Illuminate\Http\Response
 */
public function update(Request $request, $id)
{
    //
}

/**
 * Remove the specified resource from storage.
 *
 * @param  int  $id
 * @return \Illuminate\Http\Response
 */
public function destroy($id)
{
    //
}
}

My Profile Model:

namespace App;

use Illuminate\Database\Eloquent\Model;

class Profile extends Model
{
protected $fillable = [
  'name',

];

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

My User Model:

/**
* A User can have one Preference
* @return \Illuminate\Database\Eloquent\Relations\HasOne
*/
public function profiles() {

  return $this->hasOne('App\Profile');
}

There are numerous ways, one is simply throw an exception if the user already has a profile:

public function store(ProfileRequest $request)
{
    $user = Auth::user();
    if($user->profiles){
         abort(500);
    }
    $profile = new Profile($request->all());
    $user()->profiles()->save($profile);
    return 'saved';
}

In your template, you can show a link to either create profile or edit profile depending if the user has one yet.

You could do this check in middleware if you prefer, or make a guard.

Another nice method, as mentioned by @Maraboc in comments, is to create a blank profile on signup, so you only need an edit route.

Worth mentioning, if the user only has one profile, you should name the property 'profile' not 'profiles'

You may create empty profiles when creating new users. Another way is checkout if profile exists in your edit/update actions, like this:

public function edit()
{
    //if profile will be edited at first time, then dummy profile will be used
    $profile = Auth::user()->profile ?: new Profile();
    return view('backend.profile.edit', compact('profile'));
}

public function update(Request $request)
{
    //validate your data
    //use $fillable in Profile model to whitelist acceptable attributes
    if(Auth::user()->profile) {
        Auth::user()->profile->update($request->all());
    } else {
        $profile = new Profile($request->all());
        Auth::user()->profile()->save($profile);
    }

    //redirect to another page
}