I have a page that shows the details of a single test case. For some reason, I can't get past this error, even to send the $id. Here's my controller:
public function show($id)
{
$data =DB::table('TestCase')->where('TestCaseID', $id);
return view('managements.testcase-details')->with($data);
}
Here's the error:
in View.php line 180
at HandleExceptions->handleError('2', 'Illegal offset type', 'C:\xampp\htdocs\terkwazmng\vendor\laravel\framework\src\Illuminate\View\View.php', '180', array('key' => object(Builder), 'value' => null))
You forgot a little bit. A get and to set up data variable name. Your error means, that you pass a query builder rather than its results. The second error is that you passing a NULL value (second param in with).
$data =DB::table('TestCase')->where('TestCaseID', $id)->get();
return view('managements.testcase-details')->with('data', $data);
In view use data like you use an array: foreach($data ...).
This method solve my problem, i am showing it here as an example -
Class that we want to use -
<?php
namespace App;
use App\Helpers\ModelMPK; //MPK stands for Multi-column Primary Key handling
class AccountSession extends ModelMPK
{
protected $hidden = ["account_id", "id"];
protected $primaryKey = ['account_id', 'session'];
public $incrementing = false;
}
Customized model class, I copied the function from somewhere, i can't refer him here because I can't resource URL I get this from -
<?php
namespace App\Helpers;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
class ModelMPK extends Model
{
/**
* Set the keys for a save update query.
*
* #param \Illuminate\Database\Eloquent\Builder $query
* #return \Illuminate\Database\Eloquent\Builder
*/
protected function setKeysForSaveQuery(Builder $query)
{
$keys = $this->getKeyName();
if(!is_array($keys)){
return parent::setKeysForSaveQuery($query);
}
foreach($keys as $keyName){
$query->where($keyName, '=', $this->getKeyForSaveQuery($keyName));
}
return $query;
}
/**
* Get the primary key value for a save query.
*
* #param mixed $keyName
* #return mixed
*/
protected function getKeyForSaveQuery($keyName = null)
{
if(is_null($keyName)){
$keyName = $this->getKeyName();
}
if (isset($this->original[$keyName])) {
return $this->original[$keyName];
}
return $this->getAttribute($keyName);
}
}
my problem: My table had no auto-increment column and the laravel was trying to access the auto-increment column because Laravel assume every table has an auto-increment id, so Laravel sent me this error.
solution : add public $incrementing = false; to your Model Class
i added this in model
<pre>
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
class holding extends Model
{
public $timestamps = false;
public $incrementing = false;
public $keyType = 'string';
protected $table = 'tb_holding';
protected $primaryKey = ['qsymbol','id_user'];
protected $fillable = ['qsymbol','qlotbuy','qbuyprice','qstoploss','qlaststopls','qbuydate','idnote','id_user'];
//---> Illegal offset type while updating model
//---> because primary key more than 1 --> add this
//https://laracasts.com/discuss/channels/laravel/illegal-offset-type-while-updating-model?page=1
protected function setKeysForSaveQuery(Builder $query)
{
return $query->where('qsymbol', $this->getAttribute('qsymbol'))
->where('id_user', $this->getAttribute('id_user'));
}
</pre>
If you want to return an specific id record use this
use app\Model;
public function show($id){
$data =Model::select('n.data')->findOrFail($id);
return view('managements.testcase-details')->with($data);
}
Related
I am looking for solutions, but can't really understand. I'm new in Laravel and I want a simple instruction on how to use one model for multiple tables like CodeIgniter as follows:
Controller myController:
public function shipBuilding()
{
$data = $this->input->post();
$response = $this->MyModel->shipbuildingSave($data);
}
public function contact()
{
$data = $this->input->post();
$response = $this->MyModel->contactSave($data);
}
Model MyModel:
public function shipbuildingSave($data){
$this->db->insert('tbl_shipbuilding', $data);
return $this->db->insert_id();
}
public function contactSave($data){
$this->db->insert('tbl_contact', $data);
return $this->db->insert_id();
}
This is not how models work in Laravel. each model should be a representation of one single table.
You could, however, change the table name on booting the model up:
class Flight extends Model
{
/**
* The table associated with the model.
*
* #var string
*/
protected $table = 'example';
/**
* The "booting" method of the model.
*
* #return void
*/
protected static function boot()
{
parent::boot();
static::addGlobalScope(new AgeScope);
// Set the $this->table depending on some logic.
}
}
But again, this is probably not recommended for your case.
I am working on a project with Laravel 4.2 and I created some models and controllers and called model function from controller, the problem is after composer update command it displays this error: Call to undefined method Department::getAllParent() but before composer update it works fine. You think what is the problem with this issue? thanks in advance
Model code:
class Department extends Eloquent{
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'department';
public static function getAll()
{
$table = DB::table('department');
$object = $table->get();
return $object;
}
public static function getAllParent()
{
$table = DB::table('department');
$table->where('parent',0);
$object = $table->get();
return $object;
}
}
And Controller code:
class DepartmentController extends BaseController
{
/*
Getting all records from department
#param: none
#Accessiblity: public
#return: Object
*/
public function getAllDepartment()
{
//get data from model
$deps = Department::getAllParent();
$depAll = Department::getAll();
//load view for users list
return View::make("department.dep_list")->with('deps',$deps)->with('all',$depAll);
}
}
Don't think this is related to your issues but this might be a better way to handle these queries. you are using Eloquent and setting the table parameter. why not use Eloquent's build in power?
class Department extends Eloquent{
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'department';
public static function getAll()
{
return Department::get();
}
public static function getAllParent()
{
return Department::where('parent', 0)->get();
}
}
I think you might also be able to use $this->get(); but I can't test right now.
I have run into problems with Laravel Eloquent Model
I have a model as follow:
class Activity extends Eloquent {
protected $table = 'activity';
protected $timestamps = false;
public $item;
public $content;
public $year;
protected $fillable = array('item', 'content', 'year');
}
And the corresponding controller:
class ActivityController extends \BaseController {
public function create()
{
$activity = new Activity();
$actitity->item = 'Example';
$activity->content = 'Example content';
$activity->year = 2015;
$activity->save();
}
}
The above code should work fine and there should be a record in 'activity' table. However, all the value of columns of activity table are inserted as NULL when I run this code (except for the id column which is auto_increment).
In addition, when I var_dump the $activity (just before calling $activity->save()), the $activity with all of its properties are shown as expected (I mean, with values I've assigned before)
Is there any subtle error in my code?
You must not define database fields as actual class properties. The problem is that Laravel uses an $attributes array internally, not the models properties.
When doing
$activity->content = 'Example content';
Laravel uses the magic __set() method to update the value in it's $attributes array. But that setter method is never called because you have an actual property with that name.
What you need to do to resolve this problem is remove the properties:
class Activity extends Eloquent {
protected $table = 'activity';
protected $timestamps = false;
protected $fillable = array('item', 'content', 'year');
}
If you want to document the properties and have autocomplete support you can use the #property annotation:
/**
* #property string $item
* #property string $content
* #property int $year
*/
class Activity extends Eloquent {
This is because Eloquent uses magic setters/getters. If you did $model->randomAttribute then it would look into the models attributes array for the data.
Because you have explicitly defined each attribute it directly accesses the property and not the magic getter. When you call save(), the function saves all the data in the attributes array which contains nothing.
Remove the attribute definitions and it will work.
If you call $model->getAttributes() you will see there will be no data contained within.
Remove:
public $item;
public $content;
public $year;
from:
class Activity extends Eloquent {
protected $table = 'activity';
protected $timestamps = false;
public $item;
public $content;
public $year;
protected $fillable = array('item', 'content', 'year');
}
I'm trying to get the 'name' field of the 'users' table in my Articles (REST) controller.
These are my models:
// models/Article.php
class Article extends Eloquent {
protected $fillable = [];
protected $table = 'articles';
public function user(){
return $this->belongsTo('User','user_id');
}
public function upload(){
return $this->has_one('Upload');
}
}
// models/User.php
class User extends Eloquent implements UserInterface, RemindableInterface {
use UserTrait, RemindableTrait;
protected $fillable = array('email','password','name');
public function articles(){
return $this->hasMany('Article','user_id');
}
/**
* Get the unique identifier for the user.
*
* #return mixed
*/
public function getAuthIdentifier()
{
return $this->getKey();
}
public function getAuthPassword()
{
return $this->password;
}
public function getReminderEmail()
{
return $this->email;
}
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'users';
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = array('password', 'remember_token');
}
// controllers/ArticlesController.php
class ArticlesController extends \BaseController {
public function index() // GET (all)
{
$articles = Article::all();
foreach ($articles as $article) {
// ** ERROR ** Undefined property: Illuminate\Database\Eloquent\Relations\BelongsTo::$id
var_dump("title: ".$article->titulo." | user: ".$article->user()->id .' | email: '.$article->user()->email );
}
}
// other functions [....]
}
So..How can I get the fields from 'users' table properly?? I've been searching in the Laravel doc and this web and... I haven't' found the error :(
I've set up the database relationships on the migrations files and I've checked out the mysql databases relations diagram and everything is ok.
Have you checked the keys properly. belongsTo's second parameter should be the local key whereas hasMany's second parameter is the foreign key.
Ok so I am trying to have use the Eloquent method "firstOrCreate" within another Eloquent model.
FriendRequest Eloquent
class FriendRequest extends Eloquent {
/**
* The database table used by the model.
*
* #var string
*/
public $table = 'requests';
protected $guarded = array('id');
protected $softDelete = true;
public function friend() {
return $this->hasOne('User', 'id', 'friend_id');
}
public function user() {
return $this->hasOne('User', 'id', 'user_id');
}
public function accept() {
// FIRST YOU MUST MARK REQUEST AS ACCEPTED
// THEN SOFT DELETE REQUEST SO IT DOESN'T
// SHOW UP AS ACTIVE FRIEND REQUEST
$this->accepted = '1';
$this->save();
// CREATE FRIENDSHIP USER -> REQUESTED
$friend = Friend::firstOrNew(array('user_id' => Auth::user()->id, 'friend_id' => $this->friend_id));
$friend->save();
// CREATE FRIENDSHIP REQUESTED -> USER
$friend2 = Friend::firstOrNew(array('user_id' => $this->friend_id, 'friend_id' => Auth::user()->id));
$friend2->save();
// SOFT DELETE REQUEST BEING MARKED ACCEPTED
$status = $this->delete();
if (!$status):
return false;
else:
return true;
endif;
}
}
I've tried both firstOrCreate and firstOrNew as shown but with both times 'friend_id' and 'user_id' given in the array are set as '0'.
There is no default on the rows or indexes.
Here's the Friend Eloquent Model
class Friend extends Eloquent {
/**
* The database table used by the model.
*
* #var string
*/
public $table = 'friends';
protected $guarded = array('id');
public function user() {
return $this->hasOne('User', 'id', 'user_id');
}
public function friend() {
return $this->hasOne('User', 'id', 'friend_id');
}
}
The create() method does mass assignment and this is a big security issue, so Laravel has a protection against it. Internally it has guarded = ['*'], so all your columns will be protected against mass assignment. You have some options:
Set the fillable columns of your model:
class User extends Eloquent {
protected $fillable = array('first_name', 'last_name', 'email');
}
Or set only the ones you want to keep guarded:
class User extends Eloquent {
protected $guarded = array('password');
}
You may, at your own risk also do:
class User extends Eloquent {
protected $guarded = array();
}
Also on the difference between the firstorcreate, and firstornew:
The firstOrNew method, like firstOrCreate will attempt to locate a record in the database matching the given attributes. However, if a model is not found, a new model instance will be returned. Note that the model returned by firstOrNew has not yet been persisted to the database. You will need to call save manually to persist it:
You can also go through the Facade and use the follwing:
class Settings extends Eloquent
{
protected $table = 'settings';
protected $primaryKey = 'name';
public static function get($settingName)
{
return Settings::firstOrCreate(array('name' => $settingName));
}
}
I believe you should put your accept() function in one of your controllers instead of the model. I'm not sure how and where you're calling this function, but I think it's in the wrong place.