Laravel 5创建一个属于3个其他表的新记录

时间:2015-07-15 22:06:19

标签: mysql laravel eloquent laravel-5 laravel-5.1

我有4个表用户,区域,租赁和位置

  1. 每个用户都有多个租借
  2. 每个地区都有多个租赁
  3. 每个位置都有多个租借
  4. 基本上租赁属于所有3个表
  5. 地区 - 身份证,姓名 位置 - id,street_address,city,province,postal_code Rental - id,region_id,location_id,user_id

    我已经在这些表之间建立了hasMany和belongsTo关系,并在Tinker中对它们进行了测试,但现在我想创建和更新租借。

    • region_id通过请求传递 - $ regionId
    • user_id是Auth :: id() - $ userId
    • 通过仅获取部分请求并检查位置表来找到location_id,如果存在,我抓住location_id - $ locationId
    • 仅使用()再次使用该数据抓取剩余的帖子数据 - $ rentalData

    所有这些都适用于此,但是如何使用我提取的ID和数据创建和更新租借,这几乎可以工作:

    Location::find($locationId)->rentals()->create($rentalData);
    

    但是,需要以某种方式将$ locationId和$ userId放入混合中,并且使它们可填充似乎不正确。

    到目前为止,我一直在玩这个:

    // Retrieve the chosen rental region
    $regionId = Region::find($request->input('region_id'));
    
    // Retrieve authenticated user id
    $userId = Auth::id();
    
    // Retrieve rental location data
    $rentalLocationData = $request->only('street_address', 'city', 'province', 'country', 'postal_code');
    
    // Does the location already exist? If not create and persist it to the database
    $locationData = RentalLocation::firstOrCreate($rentalLocationData);
    $locationId = $locationData->id;
    
    // Create the rental...?
    $rental = Location::find($locationId)->rentals()->create($rentalData);
    

    更新

    所以我可以继续使用ORM去做并做到这一点,但我仍然想了解Eloquent如何超越我学习观看Laracast视频的基础知识,所以任何帮助都会受到赞赏,现在我发现它真的让人困惑:

    // Retrieve rental location data from the request
    $requestData = $request->only('street_address', 'city', 'province', 'country', 'postal_code');
    
    // Does the location already exist? If not create and persist it to the database
    $rentalLocation = RentalLocation::firstOrCreate($requestData);
    
    
    // Retrieve the foreign key ids not included in request
    $foreignKeyIds = [ 'user_id' => Auth::id(), 'rental_location_id' => $rentalLocation->id ];
    
    // Retrieve request data for creating a rental, and merge with foreign key ids
    $requestData = $request->only('region_id', 'stall', 'level', 'description');
    $rentalData = array_merge($foreignKeyIds, $requestData);
    
    // Insert new rental with all field attributes included
    DB::table('rentals')->insert($rentalData);
    

    更新

    这个解决方案怎么样?

    RentalRequest检查region_id是否存在,用户将始终是Auth :: user()。

    public function store(RentalRequest $request)
    {
        // Retrieve the authenticated user
        $User = Auth::user();
    
        // Retrieve rental location data from request
        $requestData = $request->only('street_address', 'city', 'province', 'country', 'postal_code');
    
        // Does the location already exist? If not create and persist it to the database
        $RentalLocation = RentalLocation::firstOrCreate($requestData);
    
        // Retrieve the region for inserting the rental
        $Region = Region::find($request->input('region_id'));
    
        // Retrieve rental data from request
        $requestData = $request->only('stall', 'level', 'description');
    
        // Create a new rental, fill with request data, and add relationships
        $rental = new Rental;
        $rental->fill($requestData);
        $rental->owner()->associate($User);
        $rental->location()->associate($RentalLocation);
    
        // Persist rental to database
        $rental = $Region->rentals()->save($rental);
    
        // Return rental data for capture by AngularJS interceptor
        // TODO: filter rental data don't need it all returned to client
        return response()->json([
            'rental' => $rental,
            'action' => 'rental_registered',
            'message' => trans('rental.registered')
        ]);
    }
    

1 个答案:

答案 0 :(得分:2)

我不明白为什么要这么复杂?

试试这个:

解决方案1 ​​

$User = User::find(Auth::id()); 
if(!$User) {
    return 'no user';
}

$Region = Region::find($request->input('region_id'));
if(!$Region) {
    return 'no region';
}

$locationData = $request->only('street_address', 'city', 'province', 'country', 'postal_code');
$Location = Location::firstOrCreate($locationData);

$rentalData = [
    'user_id' => $User->id, 
    'region_id' => $Region->id, 
    'location_id' => $Location->id
];
$Rental = Rental::firstOrCreate($rentalData);

解决方案2

// ->remember() for caching request to prevent many queries, for faster result use apc cache in config files, no need to use memcache when You're using 1 app server

if(!User::where('id', '=', Auth::id())->remember(1440)->exists()) {
    return 'no user';
}

if(!Region::where('id', '=', $request->input('region_id'))->remember(1440)->exists()) {
    return 'no user';
}

$locationData = $request->only('street_address', 'city', 'province', 'country', 'postal_code');
$Location = Location::firstOrCreate($locationData);

$rentalData = [
    'user_id' => $User->id, 
    'region_id' => $Region->id, 
    'location_id' => $Location->id
];
$Rental = Rental::firstOrCreate($rentalData);