I am trying to get distinct city names from a MySQL table called "city".
Here is how the controller code looks like:
public function getCityNames()
{
if(Auth::check())
{
$cities = DB::table('city')->distinct()->get();
var_dump($cities);
}
else
{
return Redirect::route('account-signin');
}
}
Here is the code for the model City:
<?php
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class City extends Eloquent
{
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'city';
/**
* Using a different primary key name
*
*/
protected $primaryKey = 'geoname_id';
public $timestamps = false;
}
The Problem
I can output distinct values from other models using the exact code as in this controller above but when I run it for the city, I get a BLANK page.
I am using Laravel 4 with detailed error messages enabled.
Of course, there is data in the 'city' table
UPDATE:
When I write the following, I get data:
public function Test()
{
return City::where('country_name', '=', 'Canada')->get();
}
But when I write the following, I get the black page? Something with the data size?
public function Test()
{
return City::all()->get();
}
Not sure if this is problem, but are you trying to view the output of var_dump($cities)?
If so, shouldn't return var_dump($cities); give you the output, rather than the empty page?
Code looks like this:
public function getCityNames()
{
if(Auth::check()) // Tip: You can apply auth filters to controllers if you want.
{
$cities = DB::table('city')->distinct()->get();
return var_dump($cities); // Add return here.
}
else
{
return Redirect::route('account-signin');
}
// If the code doesn't go anywhere, it goes here.
return "TEST";
}
I am able to access the city table fine when I ran small queries (see my update in the question). Only explanation could be that I was exceeding the browser buffer size when I was trying to get all . This table has more than 70,000 rows.
Related
I'm new to Laravel we are trying to add (https://github.com/TomLingham/Laravel-Searchy) to our project (https://github.com/wvulibraries/rockefeller-css/tree/trying-searchy) to allow the search of multiple fields in a table. I can see the package is in the vendor folder as tom-lingham for some reason I am not able to even use it. I get FatalThrowableError in DataViewController.php line 79: Class 'App\http\Controllers\Search' not Found. I followed the instructions in the github repo. Any suggestions would be appreciated.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
// Import the table and collection models
use App\Table;
use App\Collection;
use Illuminate\Support\Facades\Auth;
/**
* The controller is responsible for showing the cards data
*/
class DataViewController extends Controller {
/**
* Constructor that associates the middlewares
*
* #return void
*/
public function __construct(){
// Middleware to check for authenticated
$this->middleware('auth');
}
/**
* Show the data from the selected table
*/
public function index(Request $request, $curTable){
// Get the table entry in meta table "tables"
$curTable = Table::find($curTable);
if(!$curTable->hasAccess){
return redirect()->route('home')->withErrors(['Table is disabled']);
}
// Get and return of table doesn't have any records
$numOfRcrds = DB::table($curTable->tblNme)->count();
// check for the number of records
if ($numOfRcrds == 0){
return redirect()->route('home')->withErrors(['Table does not have any records.']);
}
// Get the records 30 at a time
$rcrds = DB::table($curTable->tblNme)->paginate(30);
// retrieve the column names
$clmnNmes = DB::getSchemaBuilder()->getColumnListing($curTable->tblNme);
// return the index page
return view('user.data')->with('rcrds',$rcrds)
->with('clmnNmes',$clmnNmes)
->with('tblNme',$curTable->tblNme)
->with('tblId',$curTable);
}
public function show(Request $request, $curTable, $curId){
// Get the table entry in meta table "tables"
$curTable = Table::find($curTable);
if(!$curTable->hasAccess){
return redirect()->route('home')->withErrors(['Table is disabled']);
}
// Check if search string and column were passed
if (strlen($curId) != 0) {
$numOfRcrds = DB::table($curTable->tblNme)
->where('id', '=', $curId)
->count();
// check for the number of records
if ($numOfRcrds == 0){
return redirect()->route('home')->withErrors(['Search Yeilded No Results']);
}
else {
// $rcrds = DB::table($curTable->tblNme)
// ->where('id', '=', $curId)
// ->get();
$rcrds = Searchy::search($curTable->tblNme)->fields('id')->query($curId)->get();
}
}
else {
return redirect()->route('home')->withErrors(['Invalid ID']);
}
// retrieve the column names
$clmnNmes = DB::getSchemaBuilder()->getColumnListing($curTable->tblNme);
// return the index page
return view('user.show')->with('rcrds',$rcrds)
->with('clmnNmes',$clmnNmes)
->with('tblNme',$curTable->tblNme)
->with('tblId',$curTable);
}
}
You're running into a namespacing issue.
Your controller is in the App\Http\Controllers namespace, so that's where it will look by default. At the top of your controller, adding a use Searchy; line alongside the existing use lines will make it work, or you can preface Searchy with a \ to tell PHP to start at the namespace root.
$rcrds = \Searchy::search(...);
I'm having an issue with Eloquent. I am returning an object that contains data but when trying to access the id of the returned field it's blank.
Here's some example code:
public function activateMobile($token)
{
/*
* Get mobile activation row matching $token
*/
$activation = $this->ci->ActivationRepository->getMobileActivationByToken($token);
/*
* Does it exist?
*/
if(empty($activation)) {
return false;
}
die($activation);
}
And here's the model:
<?php
namespace MyApp\Models;
use Illuminate\Database\Eloquent\Model;
class MobileVerification extends Model
{
protected $table = 'mobile_verification';
public function user()
{
return $this->belongsTo('\MyApp\Models\User');
}
}
For examples sake I used die to print the value of the object in string form:
{"id":7,"user_id":24,"token":"68gb","is_used":0,"verified_at":null,"created_at":"2016-11-28 18:53:52","updated_at":"2016-11-28 18:53:52"}
As you can see the id is there.
But, if I replace the die with die($activation->id) its blank. Yet, if I do die($activation->token) that's visible.
Why is the id returning blank?
I am getting the records from my database in two different points, using "get" and "find" methods. The problem is that when I am using "get", "first" or "last" the hidden fields aren't displayed (Its ok), but when I am using "find" they are still there.
<?php
//My Plugin in /plugins/Comunica/Files/src/Model/Entity/File.php
namespace Comunica\Files\Model\Entity;
use Cake\ORM\Entity;
class File extends Entity
{
protected $_hidden = ['password'];
protected $_virtual = ['protected'];
protected function _getProtected(){
return empty($this->_properties['protected']) ? false : true;
}
}
The Call Method:
<?php
$this->Files->find()->toArray();
Again. It is right when calling just one record (first, last, call), It's just wrong when trying with method "find". Any one knows how to solve this?
I have found an answer for this problem. The find returns an object that owns the entities of every result, so that you can convert them by using the "findAll" method inside the table's class.
<?php
//My Plugin in /plugins/Comunica/Files/src/Model/Entity/File.php
namespace Comunica\Files\Model\Entity;
use Cake\ORM\Entity;
use Cake\ORM\Query;//Include this class to manipulate the results
class File extends Entity
{
protected $_hidden = ['password'];
protected $_virtual = ['protected'];
protected function _getProtected(){
return empty($this->_properties['protected']) ? false : true;
}
//New formatation code
public function findAll(Query $query, array $options)
{
return $query->formatResults(function ($results) {
return $results->map(function($row) {
$row['upload_date'] = $this->dateTimeConvert($row['upload_date']);
return $row->toArray();
});
});
}
}
I solved it like this:
My main aim was to exclude hidden fields by default and have a way to explicitly get Entitys including hidden fields if I need them.
ModelsTable.php
public function beforeFind(Event $event, Query $query){
//ATTENTION: if password field is excluded we have to bypass for Auth-Component to work
if(array_key_exists('password',$_REQUEST)){
return $event;
}
$protected = $this->newEntity()->hidden;
$tableSchema = $this->schema();
$fields = $tableSchema->columns();
foreach($fields as $key => $name){
if(in_array($name,$protected)){
unset($fields[$key]);
}
}
$query->select($fields);
return $event;
}
Model.php
protected $_hidden = [
'password',
'otherSecret'
];
protected function _getHidden(){
return $this->_hidden;
}
To receive hidden fields you can simple add ->select('password') to your query, but to make it more nice I added a custom finder
ModelsTable.php
public function findSecrets(Query $query, array $options)
{
$tableSchema = $this->schema();
$fields = $tableSchema->columns();
return $query->select($fields);
}
Now you can build a query like this to receive Entity including hidden fields:
ModelsController.php
$secretModels = $this->Models->find()->find('secrets');
or whatever query you loke, simply add the custom finder
NOTE: is does not work with ->get($id) so you have to use ->findById($id)->find('secrets')->first()
I'm happy to know what you think about this solution or what you would change - feel free to commend :-)
I have two models:
class Product extends Eloquent {
...
public function defaultPhoto()
{
return $this->belongsTo('Photo');
}
public function photos()
{
return $this->hasMany('Photo');
}
}
class Photo extends Eloquent {
...
public function getThumbAttribute() {
return 'products/' . $this->uri . '/thumb.jpg';
}
public function getFullAttribute() {
return 'products/' . $this->uri . '/full.jpg';
}
...
}
This works fine, I can call $product->defaultPhoto->thumb and $product->defaultPhoto->full and get the path to the related image, and get all photos using $product->photos and looping through the values.
The problem arises when the product does not have a photo, I can't seem to figure out a way to set a default value for such a scenario.
I have tried doing things such as
public function photos()
{
$photos = $this->hasMany('Photo');
if ($photos->count() === 0) {
$p = new Photo;
$p->url = 'default';
$photos->add($p);
}
return $photos;
}
I have also creating a completely new Collection to store the new Photo model in, but they both return the same error:
Call to undefined method Illuminate\Database\Eloquent\Collection::getResults()
Has anyone done anything similar to this?
Thanks in advance!
You could create an accessor on the Product model that did the check for you. Works the same if you just wanted to define it as a method, also (good for if you want to abstract some of the Eloquent calls, use an interface for your Product in case you change it later, etc.)
/**
* Create a custom thumbnail "column" accessor to retrieve this product's
* photo, or a default if it does not have one.
*
* #return string
*/
public function getThumbnailAttribute()
{
$default = $this->defaultPhoto;
return ( ! is_null($default))
? $default->thumb
: '/products/default/thumb.jpg';
}
You might also want to look into Presenters. A bit overkill for some situations, but incredibly handy to have (and abstract things like this away from your models).
I am trying to empty the tables but I was wondering have I got the function correct?
Model:
public function removeQuote()
{
$this->db->empty_table('companyDetails,hostingDetails,layoutDetails');
}
Controller:
public function submit()
{
$data['companyContact'] = $this->quote->getCompanyDetails()->companyContact;
$this->load->view('submit',$data);
$this->quote->removeQuote();
}
Error:
Table '_quote.companyDetails,hostingDetails,layoutDetails' doesn't exist
DELETE FROM `companyDetails,hostingDetails,layoutDetails`
/**
* Empty Table
*
* Compiles a delete string and runs "DELETE FROM table"
*
* #param string the table to empty
* #return object
*/
public function empty_table($table = '')
Apparently you can't do this
$this->db->empty_table('companyDetails,hostingDetails,layoutDetails');
Instead you will have to call empty_table three times:
$this->db->empty_table('companyDetails');
$this->db->empty_table('hostingDetails');
$this->db->empty_table('layoutDetails');
You can always hack CodeIgniter DB_active_rec.php file so that it fits your needs.
In your controller you have to load the model first (if it's not auto loaded)
$this->load->model('quote'); // Assuming your model name is 'quote'
before you use the function from that model as you used in your controller as follows
$data['companyContact'] = $this->quote->getCompanyDetails()->companyContact;
and load the view at last, after all code has been executed even after following line
$this->quote->removeQuote();
Just checked in CI doc empty_table doesn't accept multiple table names.
SOLUTION ONE
$this->db->truncate('companyDetails');
$this->db->truncate('hostingDetails');
$this->db->truncate('layoutDetails');
SOLUTION TWO
function emptytablesbycomma($stringoftables) {
$array_tablenames = explode(",", $stringoftables);
if (!empty($array_tablenames)) {
foreach ($array_tablenames as $tablename) {
$this->db->truncate($tablename);
}
}
}
Usage
$stringoftables='companyDetails,hostingDetails,layoutDetails';
$this->emptytablesbycomma($stringoftables);