Contenido del curso
Fundamentos
Bases de Datos
Operaciones CRUD
Relaciones en bases de datos
Emails
Autenticación
Cierre
Trabajando con relaciones
Resumen
Comenzaremos a usar tablas relacionadas
Contenido del curso
Trabajando con relaciones
Comenzaremos a usar tablas relacionadas
Hasta video espere que explicaran las relaciones en Eloquent que es como se deben de hacer según la documentacion, realmente queda haciendo falta para crear algo de calidad, lo mínimo necesario para el almacenamiento de datos y lo mas importante su integridad,
Link a la documentacion, por ejemplo en este proyecto se debió haber usado:
class AddExpensesToExpenseReport extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::table('expenses', function (Blueprint $table) { $table->foreign('expense_report_id')->references('id')->on('expense_reports'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('expenses', function (Blueprint $table) { $table->dropForeign(['expense_report_id']); }); } }
👍 Excelente aporte!!
Gracias bro!
Al archivo ExpenseController.php debes adicionar las siguientes líneas:
use App\ExpenseReport; use App\Expense;
Validación de Expenses en la función store:
public function store(Request $request, ExpenseReport $expenseReport) { $validaData = $request->validate([ 'description' => 'required|min:3', 'amount' => 'required|integer|min:1' ]); $expense = new Expense(); $expense -> description = $request -> get('description'); $expense -> amount = $request -> get('amount'); $expense -> expense_report_id = $expenseReport -> id; $expense -> save(); return redirect('/expense_reports/' . $expenseReport->id); }
en amount usaría “numeric”, sino no se puede colocar decimales
@germansayago como dices mejor si, se utiliza numeric
8:32 , de igual manera como lo hiciste con ExpenseReportController, olvidaste poner use App\ExpenseReport; en el controlador ExpenseController, lo que causa este error cuando intentas crear un nuevo expense. "Class App\Http\Controllers\ExpenseReport does not exist". Agregando ese use en el controlador Expense, se soluciona, por si le sucede a alguien más.
Si, lo noté también. Sabes que sucede, que entiendo que PHP Storm agrega automáticamente esa línea cuando se escribe esa clase dentro de la acción.
Según el ID y los plugins instalados, cuando agregas un controlles u otro elemento, estas llamadas se agregan automáticamente en el inicio del archivo
En los casos que sea necesario usar un modelo padre, como en este ejercicio, la forma en como se organiza el controlador y las rutas tiene un nombre y se llama Controladores de recursos anidados, y Laravel también nos provee una forma de crear controladores de recursos anidados de una manera super fácil.
Sólo debemos especificar la variable parent para indicar cuál es el padre y el nombre del modelo con el cual está asociado.
si ejecutas _**php artisan make:controller --help **_podrás ver estas opciones
-m, --model[=MODEL] Generate a resource controller for the given model. -p, --parent[=PARENT] Generate a nested resource controller class.
Para este caso podemos crear nuestro recurso anidado usando el siguiente comando:
php artisan make:controller -r -m Expense -p ExpenseReport ExpenseController
Igualmente podemos matricular nuestras rutas como tipo recurso y usar la funcionalidad de excluir las rutas que no necesitamos o de incluir solo las rutas que vamos a usar.
Route::resource('expense_reports.expenses','ExpenseController')->only(['create','store']);
Y finalmente en los formularios podemos hacer el llamado a las rutas con el nombre que corresponden:
Vista show.blade.php de expenses_reports. Para llamar al método create:
<a class="btn btn-primary" href="{{ route('expense_reports.expenses.create',['expense_report' => $report->id]) }}">New expense</a>
Vista create.blade.php de expenses. Para llamar al método store:
<form action="{{ route('expense_reports.expenses.store',['expense_report' => $report->id]) }}" method="POST">
Fue de gran ayuda, gracias.
Excelente aporte sin dudas!
Para los que quieran tener las validaciones en español les dejo un link validation en espanol
Me sucede esto:
Class App/http/Controllers/ExpenseReport does not exist
pero el controller si está creado :( Help me !
Hola!
Para solucionar debes agregar
use App\ExpenseReport;
en la parte inicial de tu ExpenseController.php o el controlador que estés usando
Si por alguna razón te muestra un error tipo Undefined variable “como a mi”, para solucionar debes agregar
use App\Expense;
en la parte inicial de tu ExpenseController.php o el controlador que estés usando
Apuntes: Añadimos un nuevo controlador tipo recurso para la nueva clase (y entidad) creada: - php artisan make:controller --resource ExpenseController Luego en la vista show, creamos un enlace hacia la creacion de nuevos formularios: - <a href="/expense_reports/{{ $report->id }}/expenses/create"> Luego se proceden a configurar las rutas: -Route::get('/expense_reports/{expense_report}/expenses/create', 'ExpenseController@create');
Me genero errores la carga de los expense, si le pasa lo mismo únicamente deben de agregar la ruta "use App\ExpenseReport"; en la parte superior del código en el controlador
Cuando voy a submit, del formulario expense me sale este error:
Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException The POST method is not supported for this route. Supported methods: GET, HEAD. http://127.0.0.1:8000/expense_reports/2/expenses
Tú problema está en la ruta que estás usando para guardar los detalles del Expense. Recuerda que estás usando el método post, por lo tanto en tus routes.php debes tenerlo definido como:
Route::post('/expense_reports/{expense_report}/expenses','ExpenseController@store');
En donde, post es el método que estás usando y que estás enviadno desde tu formulario, me comentas, espero te sirva.
Confirma que estes llamando correctamente al modelo, inmediatamente despues del namespace asi:
use App\Models\ExpenseReport;
Para solucionar el error: " Target class [ExpenseController] does not exist. " en Laravel 8, tomar en cuenta que en routes>web.php, debe quedar de la siguiente manera:
.... use App\Http\Controllers\ExpenseController; .... Route::get('/expense_reports/{expense_report}/expenses/create', [ExpenseController::class, 'create']); Route::post('/expense_reports/{expense_report}/expenses', [ExpenseController::class, 'store']);
Te agrego que en mi caso tuve que incorporar al inicio del ExpenseController.php
use App\Models\ExpenseReport; use App\Models\Expense;
Saludos
Tengo un problema, en create ni en store me reconoce el parametro ExpenseReport $expenseReport en las funciones para obtener luego el id, a que puede deberse? en la primeras lineas del archivo tengo puesto tanto use App\Expense como App\ExpenseReport
Hola @eantillanca por favor coloca un ejemplo de tu codigo para poder ayudarte.
yo tenia el mismo problema. No se como lo resolvi (jajajaja) aqui te dejo mi codigo para que lo veas, tal vez te sea de ayuda
<?php namespace App\Http\Controllers; use App\ExpenseReport; use App\Expense; use Illuminate\Http\Request; class ExpensesController extends Controller { /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { // } /** * Show the form for creating a new resource. * * @return \Illuminate\Http\Response */ public function create(ExpenseReport $expenseReport) { return view('expenses.create' , [ 'report' => $expenseReport ]); } /** * Store a newly created resource in storage. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function store(Request $request, ExpenseReport $expenseReport) { $expense = new Expense(); $expense->description = $request->get('description'); $expense->amount = $request->get('amount'); $expense->expense_report_id = $expenseReport->id; $expense->save(); return redirect('expense_reports/' . $expenseReport->id); }
Solución reto, validación amount y description en Expenses
public function store(Request $request, ExpenseReport $expenseReport) { $expense = new Expense(); $validData = $request->validate([ 'description' => 'required|min:3', 'amount' => 'required|numeric' ]); $expense->description = $validData['description']; $expense->amount = $validData['amount']; $expense->expense_report_id = $expenseReport->id; $expense->save(); return redirect('/expense_reports/' . $expenseReport->id); }
Bien lo de validar amount como numeric pero te falta validar el rango del número, te quedaría
'amount' => 'required|numeric|between:0,999999.99'
Tengo un problema, en el método store no me reconoce el parametro ExpenseReport $expenseReport en la función para obtener luego el id. ¿Qué podrá ser?
Confirma que estes llamando correctamente al modelo, inmediatamente despues del namespace asi:
use App\Models\ExpenseReport;
Se puede crear un archivo de migración a partir de la base de datos? Es que tengo una echa y la quiero utilizar aquí.
En este caso bastaría con configurar el nombre de tu base de datos en tu archivo .env.
Cambias:
DB_DATABASE=miBaseDeDatos
**Por: **
DB_DATABASE=miNuevaBaseDeDatos
Allí le seteas el nombre de tu base de datos y ya estaría usando tu base de datos. Aún así necesitas crear los modelos para poder conectarte a cada una de las tablas de tu db.
Recuerda que cada vez que realizas cambios en el archivo .env debes correr los comandos:
php artisan cache:clear php artisan config:cache
Espero te sea de ayuda.
Puedes hacer con el paquete Xethron/migrations-generator. Cuidado porque parece que de momento no tiene soporte para Laravel 6!
Tengo este problema al tratar de mostrar los datos en el show
ErrorException Trying to get property 'description' of non-object (View: C:\laragon\www\proyecto_laravel\resources\views\
El problema se genera en la vista, estas haciendo algo como esto:
{{ $objeto->description }}
El error te esta indicando que no puede encontrar una propiedad description
Posiblmente porque no estas pasando el objeto correctamente, confirma que desde el controlador estes pasando el objeto con el mismo nombre que la vista espera recibir.
asi:
$objeto = 'aqui estas indicando que objeto pasar'; return view('nombre_vista', compact('objeto'));
Y en ultima instancia puede ser tambien que no estes pasando un objeto sino un arreglo, eso suele suceder tambien.
Hola, una pregunta: ¿Por qué en las ruta de create de Expense se pone como parámetro de envío {expense_report} y no la variable {id}?
Porque la variable $id la "guarda" para el ámbito local de la clase Expense, es decir, la clase Expense también tiene su propio $id y como está en dicha clase, es mejor manejar el MODEL BINDING
No sé si en el curso faltó comentar o yo no escuché que el Model Binding ocupa una "type-hinted variable". Aunque veo que a muchos les ha pasado lo mismo que a mí.
Para que esta variable entienda que debe buscar una coincidencia del modelo con lo que llega en una variable, el nombre de la variable DEBE coincidir con el nombre de la variable de la ruta.
Es decir: si en la ruta "/foo/{bar}/baz" esperas que "bar" sea traducido a un modelo por el model binding, en el controlador el nombre de la variable DEBE ser $bar. public function create (Model $bar) Sólo de esa manera laravel entiende que la variable bar se debe buscar dentro del modelo Model.
Comparto la tarea, validar campos de la vista expense.create
Alguien me podria ayudar con este error porfavor:
Este error me sale cuando doy click a submit del new expense
Comprueba que hayas copiado la vista de create y no la de edit, porque a mí me dio ese error en unas clases atrás creando esa vista, y era porque necesitaba poner un campo oculto con el método put. Pero en esta clase no ha usado el método PUT en ningún momento, entonces igual es por eso, no lo sé.
Si pones una captura del código de la vista de create expense será más fácil echarte una mano!! :)
Verifica la dirección que tienes colocada en el form