I have three Database Tables.
CREATE TABLE `tblprojecttype` (
`ProjectTypeID` int(11) NOT NULL,
`ProjectType` varchar(30) NOT NULL,
`Description` varchar(500) NOT NULL,
`IsActive` tinyint(1) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `tblprojecttypecurrencyprice` (
`ProjectTypeCurrencyID` int(11) NOT NULL,
`CurrencyID` int(11) NOT NULL,
`ProjectTypeID` int(11) NOT NULL,
`Price` decimal(10,0) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `tblcurrency` (
`CurrencyID` int(11) NOT NULL,
`Currency` varchar(100) NOT NULL,
`IsActive` tinyint(1) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Models
class Currency_Model extends Model
{
protected $table = "tblcurrency";
protected $primaryKey = "CurrencyID";
public $timestamps = false;
}
class ProjectType_Model extends Model
{
protected $table = "tblprojecttype";
protected $primaryKey = "ProjectTypeID";
public $timestamps = false;
public function projecttypecurrencyprice()
{
return $this->hasOne('\App\Models\ProjectTypeCurrencyPrice_Model',
"ProjectTypeID");
}
}
class ProjectTypeCurrencyPrice_Model extends Model
{
protected $table = "tblprojecttypecurrencyprice";
protected $primaryKey = "ProjectTypeCurrencyID";
public $timestamps = false;
public function Currency()
{
return $this->hasOne('\App\Models\Currency_Model', "CurrencyID");
}
}
There is CurrencyID relationship and ProjectTypeID relationship
What I am trying ?
In my Laravel 5.1 code, I am trying to achive below sql statement so that I can get projecttypecurrencyprice records for each ProjectType record. Finally it should also show records from currency Table for each projecttypecurrencyprice record
$ProjectTypes = \App\Models\project\ProjectType\ProjectType_Model
::with("projecttypecurrencyprice")
->with("projecttypecurrencyprice.Currency")
->get();
What's the Problem ?
I am not able to get Currency records for each projecttypecurrencyprice record.
For ProjectTypeCurrencyPrice_Model you should change Currency relationship this way:
public function Currency()
{
return $this->belongsTo('\App\Models\Currency_Model', "CurrencyID");
}
because you have CurrencyId column in tblprojecttypecurrencyprice and you don't have any connection to ProjectTypeCurrencyPrice_Model in tblcurrency.
And to get data instead of:
$ProjectTypes = \App\Models\project\ProjectType\ProjectType_Model
::with("projecttypecurrencyprice")
->with("projecttypecurrencyprice.Currency")
->get();
you can omit 1st with:
$ProjectTypes = \App\Models\project\ProjectType\ProjectType_Model
::with("projecttypecurrencyprice.Currency")
->get();
By the way if you start this project, you should consider changes in your database structure and read about PSR in PHP - you should rather not use ProjectTypeCurrencyPrice_Model as your model name if you really don't have to, same for ProjectTypeID columns in MySQL
Related
I'm relatively new to eloquent, and have problems loading data from a hasMany relation in an app that uses eloquent as the database layer. My (simplified) code is as follows:
use Illuminate\Database\Eloquent\Model;
class Answer extends Model{
protected $table = 'answer';
public $timestamps = false;
public $incrementing = false;
protected $fillable = [
"nerdId",
"invitationid",
"eatingno",
"price",
"haspaid",
"attending",
"noeating",
];
public function topping() {
return $this->hasMany(AnswerTopping::class, 'answerid');
}
}
class AnswerTopping extends Model{
protected $table = 'eating';
public $timestamps = false;
protected $fillable = [
'answerid',
'toppingid',
'add'
];
public function answer() {
return $this->belongsTo(Answer::class);
}
}
The SQL Schema is like below
CREATE TABLE `answer` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`nerdid` int(11) NOT NULL,
`invitationid` int(11) NOT NULL,
`eatingno` tinytext,
`price` float NOT NULL,
`haspaid` tinyint(4) NOT NULL,
`attending` tinyint(1) NOT NULL DEFAULT '0',
`noeating` tinyint(4) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2119 DEFAULT CHARSET=utf8;
CREATE TABLE `eating` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`answerId` int(11) NOT NULL,
`toppingid` int(11) NOT NULL,
`add` tinyint(4) NOT NULL DEFAULT '1',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=280 DEFAULT CHARSET=utf8;
I then do the following query:
$answer = Answer::with('topping')->find(32);
return $answer->toJson());
This results in a json like the following
{"id":32,"nerdid":1,"invitationid":54,"eatingno":"51","price":60,"haspaid":1,"attending":2,"noeating":0,"topping":[]}
Raw SQL query shows me that I do have data in the relation, so it should return more in "topping".
UPDATE
Checking sql queries in mysql (Setting it up for logging), I see that it actually do the expected queries on the database:
select * from `answer` where `answer`.`id` = 32 limit 1;
select * from `eating` where `eating`.`answerid` in (32);
Manually executing the SQL are giving me 2 entries in the eating table. But they are not showing up on the upper "Answer" json.
Found the culprit.. db schema for the "eating" table, had answerId (uppercase I), and the relation in hasMany used answerid (lowercase i), which apparently confused eloquent..
Now I get the expected json..
I am going to implement a query that retrieves all my blogs with their tags. I am using Laravel Eloquent polymorphic relations but I have an error that is Column not found: 1054 Unknown column 'taggables.tags_model_id' in 'field list'. All my codes in both laravel and my SQL are presented below:
my tables:
create table tags
(
id int auto_increment
primary key,
name varchar(200) null,
created_at timestamp default CURRENT_TIMESTAMP not null,
updated_at timestamp null,
deleted_at timestamp null
);
create table taggables
(
id int auto_increment
primary key,
tag_id int null,
taggable_type varchar(512) null,
taggable_id int null,
created_at timestamp default CURRENT_TIMESTAMP not null,
updated_at timestamp null,
deleted_at timestamp null,
constraint fk23
foreign key (tag_id) references tags (id)
on update cascade on delete cascade
);
create index taggables_tag_id_index
on taggables (tag_id);
create table blog
(
id int auto_increment
primary key,
title varchar(200) null,
passage text null,
author varchar(200) null,
category varchar(200) null,
img_url varchar(200) null,
created_at timestamp default CURRENT_TIMESTAMP not null,
updated_at timestamp null,
deleted_at timestamp null,
user_id int not null,
category_id int null,
constraint fk18
foreign key (user_id) references users (id)
on update cascade on delete cascade,
constraint fk19
foreign key (category_id) references blog (id)
on update cascade on delete cascade
);
create index blog_index
on blog (category_id);
create index blog_users_index
on blog (user_id);
Eloquent Models
class BaseModel extends Model
{
protected $table;
protected $primaryKey;
use SoftDeletes;
}
class BlogModel extends BaseModel
{
protected $table = 'blog';
protected $primaryKey = 'id';
public function tags()
{
return $this->morphToMany(TagsModel::class,"taggable");
}
}
class TagsModel extends BaseModel
{
protected $table = 'tags';
protected $primaryKey = 'id';
public function blog()
{
return $this->morphedByMany(BlogModel::class,"taggable");
}
}
when I called this query the result is an empty array
public function getItemsWithTags(array $attr)
{
return BlogModel::find(1)->tags;
}
thank you very much.
Laravel's polymorphic relations use reflection, by default, to determine the name of your key columns. Because your model is called TagModel, Laravel assumes that the foreign key will be tag_model_id.
// Illuminate\Database\Eloquent\Model
public function getForeignKey()
{
return Str::snake(class_basename($this)).'_'.$this->getKeyName();
}
You can fix this by explicitly passing the correct foreign key to the morphedByMany method:
public function tags()
{
return $this->morphedByMany(TagsModel::class, 'taggable', null, 'tag_id');
}
You can't do an intermediate parenting class like BaseModel. Because it won't work in the Laravel with property $table, try to do this:
class BlogModel extends Model
{
use SoftDeletes;
protected $table = 'blog';
protected $primaryKey = 'id';
public function tags()
{
return $this->morphToMany(TagsModel::class,"taggable");
}
}
class TagsModel extends Model
{
use SoftDeletes;
protected $table = 'tags';
protected $primaryKey = 'id';
public function blog()
{
return $this->morphedByMany(BlogModel::class,"taggable");
}
}
Try this example, you need to reference 'tags' in your eloquent method.
BlogModel::with('tags')->find(1);
I have three Database Tables.
CREATE TABLE `tblprojecttype` (
`ProjectTypeID` int(11) NOT NULL,
`ProjectType` varchar(30) NOT NULL,
`Description` varchar(500) NOT NULL,
`IsActive` tinyint(1) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `tblprojecttypecurrencyprice` (
`ProjectTypeCurrencyID` int(11) NOT NULL,
`CurrencyID` int(11) NOT NULL,
`ProjectTypeID` int(11) NOT NULL,
`Price` decimal(10,0) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `tblcurrency` (
`CurrencyID` int(11) NOT NULL,
`Currency` varchar(100) NOT NULL,
`IsActive` tinyint(1) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Models
class Currency_Model extends Model
{
protected $table = "tblcurrency";
protected $primaryKey = "CurrencyID";
public $timestamps = false;
}
class ProjectType_Model extends Model
{
protected $table = "tblprojecttype";
protected $primaryKey = "ProjectTypeID";
public $timestamps = false;
public function projecttypecurrencyprice()
{
return $this->hasOne('\App\Models\ProjectTypeCurrencyPrice_Model',
"ProjectTypeID");
}
}
class ProjectTypeCurrencyPrice_Model extends Model
{
protected $table = "tblprojecttypecurrencyprice";
protected $primaryKey = "ProjectTypeCurrencyID";
public $timestamps = false;
public function Currency()
{
return $this->belongsTo('\App\Models\Currency_Model', "CurrencyID");
}
}
There is CurrencyID relationship and ProjectTypeID relationship
What I am trying ?
In my Laravel 5.1 code, I am trying to achive below sql statement so that I can get projecttypecurrencyprice records for each ProjectType record. Finally it should also show records from currency Table for each projecttypecurrencyprice record
$ProjectTypes = \App\Models\project\ProjectType\ProjectType_Model
::with("projecttypecurrencyprice")
->with("projecttypecurrencyprice.Currency")
->get();
What's the Problem ?
I am getting all Currency records for each projecttypecurrencyprice record. I just want those where currency ID = 1
You need to apply additional criteria when fetching related ** projecttypecurrencyprice** objects. You can do that with whereHas() method. The following code should do the trick:
$ProjectTypes = \App\Models\project\ProjectType\ProjectType_Model
::with("projecttypecurrencyprice")
->with(["projecttypecurrencyprice.Currency" => function($query) {
$query->where('CurrencyID', 1);
}])
->get();
If I am not missing something, shouldn't a simple where() clause in your eloquent query builder do the trick?
Like this:
$ProjectTypes = \App\Models\project\ProjectType\ProjectType_Model
::with("projecttypecurrencyprice")
->with("projecttypecurrencyprice.Currency")
->where('id', 1)
->get();
(not tested of course, please don't slap me)
I have three Database Tables.
CREATE TABLE `tblproject` (
`ProjectID` int(11) NOT NULL,
`ProjectStatusID` varchar(30) NOT NULL,
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `tblSkills` (
`SkillID` int(11) NOT NULL,
`Skill` varchar(100) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `tblprojectSkills` (
`ProjectSkillID` int(11) NOT NULL,
`ProjectID` int NOT NULL,
`SkillID` int NOT NULL,
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
In the above tables. SkillID is related in tblSkills and tblprojectSkills.
ProjectID is related in Project and projectSkills Table
My project Model is below.
class Project_Model extends Model
{
protected $table = "tblproject";
protected $primaryKey = "ProjectID";
public $timestamps = false;
public function ProjectSkills() {
return $this->hasMany('\App\Models\ProjectSkill_Model', 'ProjectID');
}
}
Database Query in laravel 5.1 is below.
\App\Models\Project\Project_Model
::with('ProjectSkills')
->where('ProjectID', '=', $ProjectID)->first();
Question
I can get the Skill ID, But, How can I get the Skill Name from Skill Table ?
You can select the fields you want with a closure:
\App\Models\Project\Project_Model
::with('ProjectSkills' => function($q)
{
$q->select('SkillID', 'Skill');
})
->where('ProjectID', '=', $ProjectID)->first();
Alternatively, you could add the fields you want directly in the relation of your model:
public function ProjectSkills() {
return $this->hasMany('\App\Models\ProjectSkill_Model', 'ProjectID')
->select('SkillID', 'Skill');
}
I am trying to display all table records that match a foreign key id using Laravel. However, my query is not pulling any records into the view.
How do I find all of the records which match a foreign key id that is passed into the function?
routes.php:
Route::get('/personas/{idPersona}/quotes', 'QuoteController#index');
QuoteController.php:
public function index($id)
{
$quotes = Quote::where('idPersona', $id)->get();
return View::make('quotes.index')->with('quotes', $quotes);
}
views/quotes/index.blade.php:
<h2> Quotes </h2>
#foreach($quotes as $quote)
<li>{{ $quote }}</li>
#endforeach
models/Quote.php
class Quote extends Eloquent {
public $timestamps = false;
protected $table = 'quote';
protected $primaryKey = 'idquote';
}
models/Persona.php
class Persona extends Eloquent {
public $timestamps = false;
protected $table = 'persona';
protected $primaryKey = 'idPersona';
}
I have 2 tables, Persona and Quote, and I am trying to pull all the quotes that match the foreign key idPersona:
CREATE TABLE `mountain`.`persona` (
`idPersona` INT NOT NULL AUTO_INCREMENT,
`fName` VARCHAR(45) NULL,
`lName` VARCHAR(45) NULL,
`mName` VARCHAR(45) NULL,
`bio` TEXT NULL,
`dateBorn` VARCHAR(45) NULL,
`dateDied` VARCHAR(45) NULL,
PRIMARY KEY (`idPersona`));
CREATE TABLE `mountain`.`quote` (
`idquote` INT NOT NULL AUTO_INCREMENT,
`quoteText` TEXT NOT NULL,
`quoteSource1` VARCHAR(100) NULL,
`quoteSource2` VARCHAR(100) NULL,
`tag1` VARCHAR(45) NULL,
`tag2` VARCHAR(45) NULL,
`tag3` VARCHAR(45) NULL,
`idPersona` INT NULL,
PRIMARY KEY (`idquote`),
INDEX `idPersona_idx` (`idPersona` ASC),
CONSTRAINT `idPersona`
FOREIGN KEY (`idPersona`)
REFERENCES `mountain`.`persona` (`idPersona`)
ON DELETE NO ACTION
ON UPDATE NO ACTION);
If you are using Eloquent, you have to get benifit of its powerfull ORM, to get all quotes that belongs to specific user you have to declare the relations first:
models/Persona.php
class Persona extends Eloquent {
public $timestamps = false;
protected $table = 'persona';
protected $primaryKey = 'idPersona';
function quotes() {
return $this->hasMany('Quote', 'idquote');
}
}
models/Quote.php
class Quote extends Eloquent {
public $timestamps = false;
protected $table = 'quote';
protected $primaryKey = 'idquote';
function persona() {
return $this->belongsTo('Persona', 'idPersona');
}
}
Then you can simply get the desired persona with all related quotes by using the relation we difined above:
QuoteController.php
public function index($id) {
$quotes = Persona::with('quotes')->find($id)->quotes;
return View::make('quotes.index')->with('quotes', $quotes);
}
It may be helpful to set up a Relationship between your Personas and your Quotes Model using Eloquent.
In your case you might want to apply a "hasMany/belongsTo" relationship as Quote->BelongsTo->Personas and a Personas has many Quotes?
http://laravel.com/docs/eloquent gives you a more detailed overview over possible relationships.
If you don't wanna use model relationships, you can simply use Database: Query Builder for more details
try this:
let's assume I have two tables:
1. reports_has_tests
2.tests. in tests table I have my foreign key.
DB::table('reports_has_tests')
->join('tests', 'tests.id', '=', 'reports_has_tests.tests_id')
->select('tests.*')->where('reports_has_tests.reports_id',$yourID)->get();
Similarly with model you can do it like this:
YourModelName::join('tests', 'tests.id', '=', 'reports_has_tests.tests_id')
->select('tests.*')->where('reports_has_tests.reports_id',$yourID)->get();
Note: I am adding this answer just to help those who don't want to use laravel models relationship and want to get the data directly from tables regarding single ID. In order to work with the above query, It is must that in your migrations/tables you have relationship.