2015-07-15 3 views
1

У меня есть 4 таблицы пользователей, регионы, аренду, и расположениеLaravel 5 Создание новой записи, что BelongsTo 3 Другие столы

  1. Каждый пользователь hasMany Аренда
  2. Каждый регион hasMany Аренда
  3. Каждый Место hasMany Аренда
  4. основном Прокат belongsTo все 3 таблицы

область - идентификатор, имя Loc ция - идентификатор, street_address, город, провинция, postal_code Аренда - идентификатор, Region_ID, LOCATION_ID, user_id

Я настроил отношения hasMany и belongsTo между этими таблицами и протестировали их в Tinker, но теперь я хочу, чтобы создать и обновить аренду.

  • Region_ID передается вверх по запросу - $ RegionId
  • user_id является в Auth :: идентификатор() - $ USERID
  • LOCATION_ID найден, беря только (часть) запрос и делать проверку таблицы местоположений, и если он существует, я захватить LOCATION_ID - $ locationId
  • оставшиеся после данных схватились с использованием только снова() для этих данных - $ rentalData

Все это работает в данный момент, но как создавать и обновлять объекты недвижимости с использованием идентификаторов и данных, я извлек, это почти работает:

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

UPDATE

Так что я могу продолжать отбрасывается при помощи 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') 
    ]); 
} 

ответ

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); 
+0

Я могу видеть, как это работает, но это выглядит, как для того, чтобы достичь этого у вас есть чтобы попасть в БД 3 или 4 раза. Существует ли более компактное решение с использованием ORM для создания/обновления этих типов отношений? – mtpultz

+1

Мы можем удалить строки User :: find(), Region :: find(), чтобы сократить запросы на 2 запроса, и останется 2 вопроса. Но в будущем вы получите проблему с безопасностью, потому что кто-то передаст недопустимые данные. Мы можем сделать это с использованием необработанного запроса, но он не даст вам большой производительности, потому что вы снова выполните 2 запроса: 1-ая вставка в местоположение, 2-ое создание записи аренды (но в необработанном запросе). – num8er

+0

Я внес изменения в код и использовал кеш, в любом случае вам придется делать проверки безопасности в будущем, и вы не можете этого избежать. – num8er

Смежные вопросы