Sunday, August 13, 2017

How to get associated table's rows in eager loading: Laravel 5.1

Leave a Comment

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 `tblprojectSkills` (   `ProjectSkillID` int(11) NOT NULL,   `ProjectID` int NOT NULL,   `SkillID` int 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;  

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');     }         }  class ProjectSkill_Model extends Model {     protected $table = "tblprojectskill";     protected $primaryKey = "ProjectSkillID";     public $timestamps = false; }  class Skill_Model extends Model {     protected $table = "tblskill";     protected $primaryKey = "SkillID";     public $timestamps = false; } 

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 ?

3 Answers

Answers 1

So your validation is kicking in on every event, focusout, etc. Hence, I added following lines to have validation only after clicking the button:

onfocusout: false, onkeyup: false, onclick: false, 

Secondly, inside your CreateErrorMessage, I have made minor changes so as to show all error messages at once. Message is an object and will have multiple error messages, hence it needs to go through $.each.

And lastly, you were checking for ErrorMessages inside the loop, which should ideally be outside, so that checking happens only once.

Below is the updated code:

$(function() {    $("form#loginForm").validate({      onfocusout: false,      onkeyup: false,      onclick: false,      rules: {        EmailAddress: "required",        Password: "required"      },      messages: {        EmailAddress: {          required: "Please enter email"        },        Password: {          required: "Please enter Password"        }      },      showErrors: function(errorMap, errorList) {        RemoveErrorElements();        CreateErrorMessage(errorList);      }    });  });    function CreateErrorMessage(errorList) {      if ($(".panel-body").find("ul.ErrorMessages").length === 0) {      $(".panel-body").prepend("<ul class='ErrorMessages'><ul>");    }      var ErrorMessages = $(".panel-body").find("ul.ErrorMessages");      $.each(errorList, function(index, Message) {      $(Message.element).parent().parent().addClass("has-error");      $(Message).each(function(k, v) {        ErrorMessages.append("<li>" + v.message + "</li>");      })      });  }    function RemoveErrorElements() {    $(".panel-body").find("ul.ErrorMessages").remove();  }
<!DOCTYPE html>  <html>    <head>    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/css/bootstrap.min.css">    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.17.0/jquery.validate.js"></script>    <script src="script.js"></script>  </head>    <body>    <div class="container">      <div class="row">        <div class="col-md-8 col-md-offset-2">          <div class="panel panel-default">            <div class="panel-heading">Login</div>            <div class="panel-body">              <form id="loginForm" class="form-horizontal form-label-left" novalidate="novalidate">                <input name="_token" type="hidden" value="qZuutEkhKvETtiuA3stgpOyOiH7FrKXUPz7C7bxe">                <div class="form-group has-error">                  <label for="EmailAddress" class="col-md-4 control-label">UserName / E-Mail Address</label>                  <div class="col-md-6">                    <input name="EmailAddress" type="text" class="form-control">                  </div>                </div>                <div class="form-group has-error">                  <label for="Password" class="col-md-4 control-label">Password</label>                  <div class="col-md-6">                    <input name="Password" type="password" value="" class="form-control">                  </div>                </div>                <div class="form-group">                  <div class="col-md-8 col-md-offset-4">                    <button type="submit" class="btn btn-primary">                                              Login                                          </button>                  </div>                </div>              </form>            </div>          </div>        </div>      </div>    </div>  </body>    </html>

Answers 2

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');     }         }  class ProjectSkill_Model extends Model {     protected $table = "tblprojectskill";     protected $primaryKey = "ProjectSkillID";     public $timestamps = false;       public function Skills() {         return $this->hasOne('\App\Models\Skill_Model', 'ProjectSkillID');     } }  class Skill_Model extends Model {     protected $table = "tblskill";     protected $primaryKey = "SkillID";     public $timestamps = false; } 

GET for skill name

$project_info = \App\Models\Project\Project_Model->where('ProjectID', '=', $ProjectID)->first();  foreach($project_info->ProjectSkills as $ProjectSkills) {      dd($ProjectSkills->skill_name); } 

Answers 3

As what you pasted, you don't need an intermediate table. And add a foreign key ProjectID reference the tblproject table.

Change the relationship method in Project_Model like this:

public function Skills() {     return $this->hasMany('\App\Models\Skill_Model', 'ProjectID'); } 

And execute the query statement:

$project = \App\Models\Project\Project_Model::where('ProjectID', $ProjectID)->with(['Skills' => function ($query) {     $query->addSelect(['SkillID', 'Skill', 'ProjectID']); }])->get(); 
If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment