I get an error like below
Call to undefined relationship [hotel_id] on model [App\Room]
Model file Hotel.php
class Hotel extends Model {
protected $primaryKey = 'id';
protected $fillable = ['hotel_name', 'hotel_area'];
public function room() {
return $this->hasMany('App\Room', 'hotel_id');
}
}
Model File Room.php
class Room extends Model {
protected $primaryKey = 'id';
protected $fillable = ['hotel_id', 'room_name', 'bonus_sum'];
public function hotel() {
return $this->belongsTo('App\Hotel', 'hotel_id');
}
}
Controller File RoomController.php
public function apiRoom() {
$rooms = Room::with('hotel');
return Datatables::eloquent($rooms)
->addColumn('action', function ($rooms) {
return '<a onclick="editForm('.$rooms->id.')" data-toggle="tooltip" data-original-title="Edit"> <i class="fa fa-pencil text-inverse m-r-10"></i> </a>'.
'<a onclick="deleteData('.$rooms->id.')" data-toggle="tooltip" data-original-title="Close"> <i class="fa fa-close text-danger"></i> </a>';
})
->escapeColumns()
->toJson();
Route file web.php
Route::get('rooms-list', 'RoomController#list');
Route::resource('room', 'RoomController', [
'except' => ['create']
]);
Route::get('api/room', 'RoomController#apiRoom')->name('api.room');
Migrate create_new_room
$table->increments('id');
$table->integer('hotel_id')->unsigned();
$table->foreign('hotel_id')->references('id')->on('hotels')->onDelete('cascade');
$table->string('room_name');
$table->string('bonus_sum');
$table->timestamps();
View File
$('#room-table').DataTable({
processing: true,
serverSide: true,
ajax: "{{ route('api.room') }}",
columns: [
{data: 'id', name: 'id'},
{data: 'hotel.hotel_name', name: 'hotel.hotel_name'},
{data: 'room_name', name: 'room_name'},
{data: 'bonus_sum', name: 'bonus_sum'},
{data: 'action', name: 'action', orderable: false, searchable: false}
]
});
It's not related to the database. There is probably an error in the ajax file.
Your hasMany has been defined incorrectly in your Hotel class.
Per the API documentation here, you need to pass an instance of the Room class through.
public function room() {
return $this->hasMany(App\Room::class, 'hotel_id');
// OR
return $this->hasMany('App\Room', 'hotel_id');
}
Same applies your Room class.
public function hotel() {
return $this->belongsTo(App\Hotel::class, 'hotel_id');
// OR
return $this->belongsTo('App\Hotel', 'hotel_id');
}
-- EDIT --
On the comment, the belongsTo function has the definition:
belongsTo($related, $foreignKey = null, $ownerKey = null, $relation = null)
For your hotel() relationship on the Room class to work, you need to pass the related models key as the second parameter. You should write it like this:
public function hotel() {
return $this->belongsTo('App\Hotel', 'id', 'hotel_id');
}
Related
I have a boolean field when I try to update from false to true for a single or multiple records it works but when trying to update it back to false it works for the first record only and can not repeat to update multiple records at the same time without refreshing the page 1- my vue component that handles the request is like this:
<template>
<div v-for="(channel, index) in items" :key="channel.id">
<a href="" #click.prevent="toggleVisibility(channel)">
<i v-if="channel.active" class="fas fa-stop default-stop" data-toggle="tooltip" title="Stop Channel">
</i>
<i v-else class="fas fa-play" data-toggle="tooltip" title="Start Channel"></i>
</a>
</div>
</template>
export default {
name: "Channels",
props: ['allChannels'],
data() {
return {
items: this.allChannels
}
},
methods: {
toggleVisibility(channel) {
axios[channel.active ? 'delete' : 'post'](`/visible-channels/${channel.name}`);
}
}
}
and my routes:
Route::post('/visible-channels/{channel}', 'ChannelsController#activate');
Route::delete('/visible-channels/{channel}', 'ChannelsController#deactivate');
my controller:
public function activate(Channel $channel, Request $request)
{
if ($request->method() == 'POST') {
$channel->update(['active' => true]);
}
return back();
}
public function deactivate(Channel $channel, Request $request)
{
if ($request->method() == 'DELETE') {
$channel->update(['active' => false]);
}
}
The model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache;
class Channel extends Model
{
protected $guarded = [];
protected $casts = [
'active' => 'boolean',
];
protected static function boot()
{
parent::boot();
static::updating(function () {
return Cache::forget('activeChannels');
});
}
public function getRouteKeyName()
{
return 'name';
}
}
Since laravel stores boolean as 1 and 0 in database, You should probably set active property to boolean in your model
That's because laravel treat false as string so when you set active to false it compares it as 'false' == true which is true so it stores 1 in database.
class Channel extends Model
{
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'active' => 'boolean',
];
}
I figured it out just change in the boot function to wait until the update finish
static::updated(function () {
return Cache::forget('activeChannels');
});
I am trying to use eloquent relationships to display the name of the patient instead of the patient id foreign key. Instead it only displays the patient id as if it doesn't see the relationship.
My controller function is:
public function getActions(){
$data = Action::all();
return DataTables::of($data)
->addColumn('name',function(Action $action){
return empty ($action->patient->first_name) ? $action->patient_id : $action->patient->first_name;
//return DB::raw("SELECT * FROM 'patients' WHERE 'patients_id' = ?", $action->patient_id);
})
->make(true);
}
My js function in the view is:
<script type="text/javascript">
$(document).ready(function (){
$('#actionTable').DataTable({
processing: true,
serverSide: true,
ajax:'{!! route('get.actions')!!}',
columns:[
{data:'action_id', name:'action_id'},
{data:'name', name:'name'},
{data:'action_status_id', name:'action_status_id'},
{data:'is_complete', name:'is_complete'},
]
});
})
</script>
My Action class is:
class Action extends Model
{
protected $table ="actions";
protected $fillable=[
'user_id', 'patient_id', 'option_id', 'action_status_id', 'is_complete', 'due_date',
];
protected $primary_key = "action_id";
public $incrementing = false;
public function patients(){
return $this->belongsTo('App\Patient','patient_id','action_id');
}
}
My Patients class is:
class Patient extends Model
{
protected $table ="patients";
protected $fillable=[
'first_name', 'last_name', 'email', 'phone', 'dob', 'gender_id', 'is_active',
];
protected $primary_key = 'patient_id';
public $incrementing = false;
public function actions(){
return $this->hasMany('App\Action','action_id','patient_id');
}
}
The problem is that you have named your relation function inside your Action model as "patients". And you are calling
$action->patient->first_name.
I suggest renaming the relation function inside your Action Model to
public function patient()
It makes more sense.
Please refer to the documentation for more clarification One to One Relationships
I'm doing a project with Laravel and Datatables. I'm using eloquent.
Datatables populates table correctly but when I do (datatables) search I receive error:
Next Illuminate\Database\QueryException: SQLSTATE[42S22]: Column not
found: 1054 Unknown column 'sector.location.location_name' in 'where
clause' ...
Can you please recommend a solution to this?
Tables structure:
--change_logs table
id
username
sector_id
operation_id
layer_category_id
object_name
--sectors table
id
sector_name
location_id
--locations table
id
location_name
In datatables Ajax I use
{data: 'sector.location.location_name', name:
'sector.location.location_name'}, and I receive error "Column not
found: 1054 Unknown column 'sector.location.location_name' in
'where clause'"
If I use name of the tables and not the objects like this:
{data: 'sector.location.location_name', name: '**sectors.locations.location_name**'},
I still receive an error:
Column not found: 1054 Unknown column
'sectors.locations.location_name' in 'where clause'
Data is loaded correctly in datatables table but search is not working
//changelogs.blade.php
var table = $('.data-table').DataTable({
processing: true,
serverSide: true,
ajax: "{{ route('change_logs.index') }}",
columns: [
//{data: 'DT_RowIndex', name: 'DT_RowIndex'},
{data: 'id', name: 'change_logs.id'},
{data: 'user.name', name: 'user.name'},
{data: 'user.username', name: 'user.username'},
{data: 'sector.location.location_name', name: 'sector.location.location_name'},
{data: 'sector.sector_name', name: 'sector.sector_name'},
{data: 'layer_category.layer.layer_name', name: 'layer_category.layer.layer_name'},
{data: 'layer_category.category_name', name: 'layer_category.category_name'},
{data: 'object_name', name: 'object_name'},
{data: 'operation.operation_name', name: 'operation.operation_name'},
{data: 'action', name: 'action', orderable: false, searchable: false},
]
});
//controller
$data = ChangeLog::with('user','sector','operation','layer_category' )->select('change_logs.*');
return Datatables::of($data)
//class ChangeLog
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class ChangeLog extends Model
{
protected $fillable = [
'username', 'sector_id','operation_id', 'layer_category_id', 'object_name'
];
protected $hidden = [
];
public function location()
{
return $this->belongsTo('App\Location');
}
public function user()
{
//return $this->belongsTo('App\User');
return $this->belongsTo('App\User', 'username', 'username');
}
public function sector()
{
return $this->belongsTo('App\Sector')->with('location');
}
public function operation()
{
return $this->belongsTo('App\Operation');
}
public function layer_category()
{
return $this->belongsTo('App\LayerCategory')->with('layer');
}
}
//class Sector
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Sector extends Model
{
protected $fillable = [
'sector_name','location_id',
];
protected $hidden = [
];
public function location()
{
return $this->belongsTo('App\Location');
}
}
//class Location
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Location extends Model
{
protected $fillable = [
'location_name',
];
protected $hidden = [
];
public function sectors()
{
return $this->hasMany('App\Sector');
}
}
Have you defined a relationship that maps the locations to the sector? From your table structure, a location can have multiple sectors thats why we have the location_id in the sectors. So it is expected you define this relationship in the respective models.
app\Sector.php
...
public function location() {
return $this->belongsTo('App\Location');
}
app\Location.php
...
public function location() {
return $this->hasMany('App\Sector');
}
I'm using MySQL Database. I have select2 js with multiple value
Here is my code
My Blade View And JS
<input type="text" class="form-control tools_id" name="tools_id[]" multiple/>
var $tools_id = jQuery('.tools_id');
$tools_id.select2({
multiple: true,
placeholder: 'Tools',
ajax: {
url: 'sample/gettools',
dataType: 'json',
delay: 250,
data: function (term, page) {
return {
q: term, //search term
};
},
results: function (data) {
return {
results: $.map(data, function (item) {
return {
text: item.tools,
id: item.tools_id
}
})
};
},
cache: true
}
});
My Model
namespace App;
use Illuminate\Database\Eloquent\Model;
class Sample extends Model
{
protected $primaryKey = 'id';
public $incrementing = false;
protected $table = 'lab_sample';
protected $casts = [
'tools_id' => 'array'
];
protected $fillable = ['name','summary','tools_id'];
}
My Controller
public function store(Request $request)
{
$sample = Sample::create([
'name' => $request->name,
'summary' => $request->summary,
'tools_id' => $request->input('tools_id'),
]);
return Response::json($sample);
}
My code was successfully save the data, but the problem is when i selected more than one value/tags, it saved the array value (tools_id) like this
["20,21"]
Where it supposed to be like this
["20","21"]
I'm having an issue with Eloquent relationship. The relationship is... Each User can have an Owner which is also a user.
When I try to fetch User with Parent:
On *nix OS and PHP 5.4.20, I get same User as Parent so parent and user both are same.
Whereas on PHP5.4.7 (Win 7 if that matters), it returns correct data. By the way this code is an Event Handler of some event.
User Model
class User extends Eloquent implements UserInterface, RemindableInterface, PresentableInterface {
protected $fillable = array(
'first_name', 'last_name', 'email', 'password', 're_type_password', 'birth_date',
'phone', 'address', 'state', 'city', 'zip', 'profile_pic', 'owner_id', 'can_edit_appointments',
'can_accept_invitations', 'can_edit_profile', 'can_receive_notification', 'is_active', 'is_admin', 'token', 'failed_login_attempts_count'
);
public function __construct($validator = null, $subAccountValidator = null)
{
parent::__construct();
$this->validator = $validator ?: App::make('ReminderMillie\Services\Validators\UserValidator');
$this->subAccountValidator = $subAccountValidator ?: App::make('ReminderMillie\Services\Validators\SubAccountValidator');
}
public function getDates()
{
return array('created_at', 'updated_at', 'birth_date');
}
/**
* Relations
*/
public function business()
{
return $this->hasOne('Business', 'owner_id');
}
public function parent()
{
return $this->belongsTo('User', 'owner_id');
}
public function subAccounts()
{
return $this->hasMany('User', 'owner_id');
}
}
I think you inverse is incorect...
please check this
public function parent()
{
return $this->belongsTo('User');
}
public function subAccounts()
{
return $this->hasMany('User', 'id', 'owner_id');
}