updated_at unknown timestamps sqlstate optimizar not lentas found false consultas column 42s22 php laravel eloquent

php - unknown - Laravel, ¿Cómo usar las condiciones de la columna de relación?



sqlstate[42s22]: column not found: 1054 unknown column ''updated_at'' in ''field list'' (5)

Estoy usando Laravel y tengo un pequeño problema con Eloquent ORM ... Puedo hacer que esto funcione simplemente con la consulta SQL usando un JOIN pero parece que no puedo hacer que funcione con Eloquent.

Esto es lo que quiero, tengo dos tablas. uno es ''Restaurantes'' y otro es ''Restaurante_Instalaciones''.

Las tablas son simples ... y las relaciones uno a uno. como que hay una mesa de restaurant con id , name , slug , etc. y otra mesa llamada restaurant_facilities con id , restaurant_id , wifi , parking , etc.

Ahora lo que quiero hacer es ... cargar todos los restaurantes que tengan wifi = 1 o wifi = 0 ... ¿Cómo puedo hacer eso con Eloquent? He intentado cargar, tablas dinámicas, con (), colecciones () y ¡nada parece funcionar!

¡El mismo problema que tengo para una relación de Muchos a Muchos para las cuisines ! Tengo la misma mesa de restaurant y una mesa de cuisine y una mesa de restaurant_cuisine_connection ..

pero ¿cómo cargo todos los restaurantes dentro de una cocina específica usando su identificación?

Esto funciona.

Cuisine::find(6)->restaurants()->get();

pero quiero cargar esto de Restaurant :: modelo no de cocinas ... porque tengo muchas condiciones encadenadas juntas ... es para una página de búsqueda y filtrado / navegación.

¿Alguna idea o forma? He estado luchando con esto durante 3 días y todavía no tengo respuesta.

Modelos de ejemplo:

class Restaurant extends Eloquent { protected $table = ''restaurants''; public function facilities() { return $this->hasOne(''Facilities''); } } class Facilities extends Eloquent { protected $table = ''restaurants_facilities''; public function restaurant() { return $this->belongsTo(''Restaurant''); } }

PD: Esto parece estar funcionando ... pero esto no es Eloquent ¿verdad?

Restaurant::leftJoin( ''cuisine_restaurant'', ''cuisine_restaurant.restaurant_id'', ''='', ''restaurants.id'' ) ->where(''cuisine_id'', 16) ->get();

Además, ¿cuál es el mejor método para encontrar un recuento de restaurantes que tienen un valor de columna específico sin otra consulta? como ... tengo que encontrar el total de restaurantes que tienen estacionamiento = 1 y wifi = 1?

Por favor ayuda en esto.

Gracias.


¿Tiene absolutamente que cargarlo desde el modelo de restaurante? Para resolver el problema, generalmente lo abordo de forma inversa.

Facilities::with(''restaurant'')->where(''wifi'' ,''='', 0)->get();

Esto obtendrá todas las instalaciones del restaurante que coincidan con sus condiciones, y ansioso por cargar el restaurante.

Puedes encadenar más condiciones y contar el total así ...

Facilities::with(''restaurant'') ->where(''wifi'' ,''='', 1) ->where(''parking'',''='', 1) ->count();

Esto funcionará con la cocina también

Cuisine::with(''restaurant'')->where(''id'',''='',1)->get();

Esto agarra el objeto de la cocina con el id de 1 ansioso cargado con todos los restaurantes que tienen esta cocina


Me encontré con esta publicación al intentar mejorar mi metodología REST API al construir un nuevo paradigma de intercambio. Desea usar Restricciones de carga ansiosas . Supongamos que tiene una ruta de API donde está cargando un elemento compartido y su colección de subelementos como este:

/api/shared/{share_id}/subitem/{subitem_id}

Al llegar a esta ruta con una solicitud GET, desea cargar ese subelemento específico. De acuerdo, podrías cargar ese modelo con ese ID, pero ¿qué sucede si primero tenemos que validar si el usuario tiene acceso a ese elemento compartido? Una respuesta recomendaba cargar la relación inversa, pero esto podría conducir a un controlador confuso y confuso muy rápidamente. Usar restricciones en la carga ansiosa es un enfoque más ''elocuente''. Entonces lo cargaríamos así:

$shared = Shared::where(''id'', $share_id) ->with([ ''subitems'' => function($query) use ($subitem_id) { $query->where(''subitem_id'', $subitem_id) }]);

Entonces, donde solo quiero el subelemento que tiene esa identificación. Ahora podemos verificar si se encontró o no haciendo algo como esto:

if ($shared->subitems->isEmpty())

Como los subelementos son una colección (matriz de subelementos) devolvemos el subelemento [0] con esto:

return $shared->subitems[0];


No veo nada de malo en hacer la combinación izquierda aquí, si tiene que cargar desde el modelo de restaurante. Podría resumirlo en un método en mi modelo de restaurante, así:

class Restaurant extends Eloquent { protected $table = ''restaurants''; // will be default in latest L4 beta public function facility() { return $this->hasOne(''Facility''); } // Or, better, make public, and inject instance to controller. public static function withWifi() { return static::leftJoin( ''restaurant_facilities'', ''restaurants.id'', ''='', ''restaurant_facilities.restaurant_id'' )->where(''wifi'', ''='', 1); } }

Y luego, desde tus rutas:

Route::get(''/'', function() { return Restaurant::withWifi()->get(); });

En el camino, no he probado ese código, pero creo que debería funcionar. En su lugar, podría utilizar la carga ansiosa con una restricción, pero eso solo especificará si el objeto de instalación es nulo o no. Todavía devolverá todos los restaurantes, a menos que especifique una cláusula where.

(PD: Me quedaría con la forma singular de Facility. Observe cómo hasOne(''Facilities'') no lee correctamente?)


Otra solución protagonizada por la función whereHas() :

$with_wifi = function ($query) { $query->where(''wifi'', 1); }; Facilities::whereHas(''restaurant'', $with_wifi)

Agradable y ordenado.


Use whereHas para filtrar por cualquier relación. No se unirá a la relación pero filtrará el modelo actual por una propiedad relacionada. También busque ámbitos locales para ayudar con situaciones como esta https://laravel.com/docs/5.3/eloquent#local-scopes

Tu ejemplo sería:

Restaurant::whereHas(''facilities'', function($query) { return $query->where(''wifi'', true); })->get(); Restaurant::whereHas(''cuisines'', function($query) use ($cuisineId) { return $query->where(''id'', $cuisineId); })->get();

Para lograr lo mismo con los ámbitos locales:

class Restaurant extends Eloquent { // Relations here public function scopeHasWifi($query) { return $query->whereHas(''facilities'', function($query) { return $query->where(''wifi'', true); }); } public function scopeHasCuisine($query, $cuisineId) { return $query->whereHas(''cuisines'', function($query) use ($cuisineId) { return $query->where(''id'', $cuisineId); }); } }

Para los ámbitos locales, NO QUIERES definirlos como métodos estáticos en tu modelo, ya que esto crea una nueva instancia del generador de consultas y te evitaría encadenar los métodos. El uso de un alcance local inyectará y devolverá la instancia actual del generador de consultas para que pueda encadenar tantos ámbitos como desee:

Restaurant::hasWifi()->hasCuisine(6)->get();

Los ámbitos locales se definen con el scope prefijo en el nombre del método y se llama sin scope en el nombre del método como en el ejemplo anterior.