Eager load nested relationships in Laravel Eloquent - eloquent

I have six models: Division, Region, Area, Branch, Mis and Policy. A division has many regions, a region has many areas, an area has many branches, a branch has many mises, a mis has one policy and a policy belongs to one mis. I want to eager load a policy with its mis, branch, area, region and division. When I try to do that, a policy is loaded with mis and branch, but the other relations are not getting loaded. Here are my models:
Division:
public function regions () {
return $this->hasMany(Region::class);
}
public function areas () {
return $this->hasManyThrough(Area::class, Region::class);
}
Region:
public function division () {
return $this->belongsTo(Division::class);
}
public function areas () {
return $this->hasMany(Area::class);
}
public function branches () {
return $this->hasManyThrough(Branch::class, Area::class);
}
Area:
public function region () {
return $this->belongsTo(Region::class);
}
public function branches () {
return $this->hasMany(Branch::class);
}
Branch:
public function area () {
return $this->belongsTo(Area::class);
}
public function mises () {
return $this->hasMany(Mis::class);
}
Mis:
public function policy () {
return $this->hasOne(Policy::class);
}
public function branch () {
return $this->belongsTo(Branch::class);
}
Policy:
public function mis () {
return $this->belongsTo(Mis::class);
}
This is how I'm trying to do the eager loading:
public function showPolicyReport () {
$policies = Policy::with('mis.branch.area.region.division')->get();
dd($policies);
}
It would be much appreciated if someone could help me find the solution.

Never mind. Actually, the relations are loaded properly. It's the dd() method which is not showing all the nested relations.

Related

Laravel 5.3 : eager load with many to many relationship

I'm trying to use eloquent to retrieve 5 last messages and display them on the dashboard.
The problem is, I need to get those messages depending on the user->role. But the message is linked to an update log. This update log is use to dispatch every dashboard message, sms to notify and email.
There is how it work :
User
public function role()
{
return $this->belongsTo(Role::class);
}
Role
public function updatelogs()
{
return $this->belongsToMany(Updatelog::class, 'role_updatelog');
}
public function users()
{
return $this->hasMany(User::class);
}
Updatelog
public function roles()
{
return $this->belongsToMany(Role::class, 'role_updatelog');
}
public function dashboard_message()
{
return $this->hasOne(DashboardMessage::class);
}
DashboardMessage
public function updatelog()
{
return $this->belongsTo(Updatelog::class);
}
There is what I tried:
$dashmessages = DashboardMessage::with(array('updatelog' => function($q) use($user) {
$q->with(array('roles' => function($q2) use($user) {
$q2->whereHas($user->role_id);
}));
$q->whereHas('institution');
}))->with('updatelog.institution.rate_grids')->orderBy('updated_at', 'DESC')->take(5)->get();
I'm getting the last 5 DashboardMessages without the role constraint. What am I doing wrong?
EDIT---------------------------------------------------
I just tried something else and it work perfectly:
$updatelog = Updatelog::whereHas('roles', function ($query) use($user) {
$query->where('role_id', $user->role_id);
})
->whereHas('dashboard_message')
->with('dashboard_message')
->whereHas('institution')
->with('institution')
->with('rate_grid')
->take(5)->get();

ASP.NET 5 WebAPI

I am creating API post methods in ASP.NET 5 webapi. I have a requirement that I need to create overloaded post methods as follows.
[HttpPost]
public bool LogInfo([FromBody]LogEventModel value)
{
}
[HttpPost]
public bool LogInfo (String strInformation)
{
}
I tried multiple options to set the routing parameters as follows.
[HttpPost("LogInfo/{strInformation}")]
(or)
[Route("LogInfo/{strInformation}")]
But its not working. I hope I am messing up something here. Can anyone help ?
I don't think this is possible anymore. Because of the fact that Controllers and Web API Controllers are now the same thing, routing has been unified also. You can read more about it here.
So what I would do is, this is my controller code:
public class HomeController : Controller
{
// GET: /<controller>/
public IActionResult Index()
{
ViewBag.Title = $#"{nameof(HomeController)}-{nameof(Index)}";
return View();
}
[HttpPost]
[Route("home/setsomething2", Name = "SetSomething2")]
public void SetSomething([FromBody]SomeValueModel someValue)
{
var value = someValue;
}
[HttpPost]
[Route("home/setsomething1", Name = "SetSomething1")]
public void SetSomething(String someValue)
{
var value = someValue;
}
}
public class SomeValueModel
{
[JsonProperty("somevalue")]
public string SomeValue { get; set; }
}
And this is how I called it from the view Index.cshtml:
function postSomething1() {
var url = "#Url.RouteUrl("SetSomething1", new {someValue = "someValue"})";
$.post(url)
.done(function () {
alert("Succes!");
})
.fail(function (response) {
console.log(response);
alert("Fail!");
});
}
function postSomething2() {
var url = "#Url.RouteUrl("SetSomething2")";
$.ajax({
contentType: 'application/json',
data: JSON.stringify({ "somevalue": "myvalue" }),
dataType: 'json',
success: function () {
alert("Succes!");
},
error: function () {
alert("Error!");
},
processData: false,
type: 'POST',
url: url
});
}
You could however make the routing of SetSomething2 more RESTful, like:
[Route("home/setsomething/{someValue}", Name = "SetSomething2")]
Note: Notice how the path 'home/setsomething/' is cleaned from numbers, so this would be my prefered way to go.
And if you REALLY don't want to make different routes you can't use named routes. So you'll have to ditch the names like:
[Route("home/setsomething")]
And:
[Route("home/setsomething/{someValue}")]
And then call them in jQuery like for instance:
var url = "home/setsomething/somevalue";
Here is what I do.
I prefer specifying routes for each controller by annotating them with:
[Route("[controller]/[action]")]
Then an action may look like:
[HttpPost]
[ActionName("GetSomeDataUsingSomeParameters")]
public List<Thing> GetSomeDataUsingSomeParameters([FromBody] MyParameters parms)
{
return Repo.GetData(parms);
}
The request may look like:
http://myhost/mycontroller/GetSomeDataUsingSomeParameters
The parameters are passed as a Json structure in the body by the POST method. For example:
{"Parameter1":1,"Parameter2":"a string"}
The request should also specify:
Content-Type: application/json
So let's say your class Thing is:
public class Thing
{
public int Id { get; set; }
public string Name { get; set; }
}
Then the response could be (with two things found in the database):
[{"Id":1,"Name":"First thing"},{"Id":2,"Name":"Another thing"}]

Nullpointer exception in CompositePlanningValueRangeDescriptor.extractValues

I'm facing a NPE when trying to solve my solution:
Exception in thread "main" java.lang.NullPointerException
at java.util.ArrayList.addAll(ArrayList.java:472)
at org.drools.planner.core.domain.variable.CompositePlanningValueRangeDescriptor.extractValues(CompositePlanningValueRangeDescriptor.java:46)
at org.drools.planner.core.domain.variable.PlanningVariableDescriptor.extractPlanningValues(PlanningVariableDescriptor.java:259)
at org.drools.planner.core.heuristic.selector.variable.PlanningValueSelector.initSelectedPlanningValueList(PlanningValueSelector.java:91)
at org.drools.planner.core.heuristic.selector.variable.PlanningValueSelector.phaseStarted(PlanningValueSelector.java:73)
at org.drools.planner.core.heuristic.selector.variable.PlanningValueWalker.phaseStarted(PlanningValueWalker.java:64)
at org.drools.planner.core.heuristic.selector.variable.PlanningVariableWalker.phaseStarted(PlanningVariableWalker.java:62)
at org.drools.planner.core.constructionheuristic.greedyFit.decider.DefaultGreedyDecider.phaseStarted(DefaultGreedyDecider.java:62)
at org.drools.planner.core.constructionheuristic.greedyFit.DefaultGreedyFitSolverPhase.phaseStarted(DefaultGreedyFitSolverPhase.java:112)
at org.drools.planner.core.constructionheuristic.greedyFit.DefaultGreedyFitSolverPhase.solve(DefaultGreedyFitSolverPhase.java:57)
at org.drools.planner.core.solver.DefaultSolver.runSolverPhases(DefaultSolver.java:190)
at org.drools.planner.core.solver.DefaultSolver.solve(DefaultSolver.java:155)
at de.haw.dsms.applicationcore.planning.BalancingApp.main(BalancingApp.java:47)
I have annotated my planning entity with the following annotations to collect the value range from two lists in the solution:
#PlanningEntity
public class ScheduleItem implements Cloneable{
private ChangeOfferEvent item;
#PlanningVariable()
#ValueRanges({
#ValueRange(type = ValueRangeType.FROM_SOLUTION_PROPERTY, solutionProperty = "offers"),
#ValueRange(type = ValueRangeType.FROM_SOLUTION_PROPERTY, solutionProperty = "dummies")
})
public ChangeOfferEvent getItem() {
return item;
}
public void setItem(ChangeOfferEvent item) {
this.item = item;
}
public ScheduleItem() {
this.item = null;
}
...
This is the solution:
public class ProductionConsumptionBalancing implements Solution<HardAndSoftLongScore> {
/*
* Problem facts
*/
// The grid entity offers
private List<ChangeOfferEvent> offers;
// Placeholder events to represent "not used schedule items"
private List<PlaceholderOfferEvent> dummies;
// The total energy consumption in the grid
// [Watt]
private TotalEnergyConsumption totalElectricityConsumption;
// The total energy production in the grid
// [Watt]
private TotalEnergyProduction totalElectricityProduction;
public List<ChangeOfferEvent> getOffers() {
return offers;
}
public void setOffers(List<ChangeOfferEvent> offers) {
this.offers = offers;
}
public List<PlaceholderOfferEvent> getDummies() {
return dummies;
}
public void setDummies(List<PlaceholderOfferEvent> dummies) {
this.dummies = dummies;
}
public TotalEnergyConsumption getTotalElectricityConsumption() {
return totalElectricityConsumption;
}
public void setTotalElectricityConsumption(
TotalEnergyConsumption totalElectricityConsumption) {
this.totalElectricityConsumption = totalElectricityConsumption;
}
public TotalEnergyProduction getTotalElectricityProduction() {
return totalElectricityProduction;
}
public void setTotalElectricityProduction(
TotalEnergyProduction totalElectricityProduction) {
this.totalElectricityProduction = totalElectricityProduction;
}
/*
* Problem entities
*/
private List<ScheduleItem> schedule;
#PlanningEntityCollectionProperty
public List<ScheduleItem> getSchedule() {
return schedule;
}
public void setSchedule(List<ScheduleItem> schedule) {
this.schedule = schedule;
}
...
The strange thing about this is, that during debugging I discoverd that it is the parameter "planningEntity" which is null and not the values in the solution.
Does anybody encounter the same issue or does know how to solve this?
Thanks and best regards!
PS:
It seems like this is coming from the method initSelectedPlanningValueList:
private void initSelectedPlanningValueList(AbstractSolverPhaseScope phaseScope) {
90 if (planningVariableDescriptor.isPlanningValuesCacheable()) {
91 Collection<?> planningValues = planningVariableDescriptor.extractPlanningValues(
92 phaseScope.getWorkingSolution(), null);
93 cachedPlanningValues = applySelectionOrder(planningValues);
94 } else {
95 cachedPlanningValues = null;
96 }
97 }
PSPS:
Problem solved.
The issue appeared because I forgot to link the clone's dummies-attribute to the original dummies list. So the dummies list in the cloned solution was null.
#Override
public Solution<HardAndSoftLongScore> cloneSolution() {
ProductionConsumptionBalancing clone = new ProductionConsumptionBalancing();
// Transfer consumption and production values
clone.totalElectricityConsumption = this.totalElectricityConsumption;
clone.totalElectricityProduction = this.totalElectricityProduction;
// Shallow copy offer lists (shouldn't change)
clone.offers = this.offers;
// Shallow copy of dummy list
clone.dummies = this.dummies;
// Deep copy schedule
...
Starting from 6.0.0.Beta1, OptaPlanner (= Drools Planner) supports automatic cloning out-of-the-box. So you don't need to implement the cloneSolution() method no more, because planner figures it out automatically. Because you don't need to implement the method no more, you can't implement it incorrectly.
Note that you can still implement a custom clone method if you really want too.

EF: Partial class - acces to the adapter?

let's say that I have a table TabA
namespace MyProject.Models.Database //<-- the same namespace as the EF's dbmx file
{
public partial class TabA
{
public void Foo()
{
//
}
}
}
Inside the Foo method, I need to perform some operations on the other table which isn't asosiated with the TabA In the other words, I need to access to the Entity Framework adapter inside that method. Is it possible ?
Edit
the answer is here https://stackoverflow.com/a/11135157/106616
If I understand the problem correctly, I assume you have your reasons for wanting to work on another entity from the TabA entity. If this is true, I can see two ways of doing this.
A) If you want your changes to be applied at the same time as other potential changes to the TabA Entity, then you can always pass in the context as a parameter:
namespace MyProject.Models.Database //<-- the same namespace as the EF's dbmx file
{
public partial class TabA
{
public void Foo(YourDbContext context)
{
var otherTableQuery = from x in context.SecondTable
where ...
select x;
foreach (var item in otherTableQuery)
{
item.Column1 = "A certain value";
}
}
}
}
Your calling method might look like:
public void DoChangesToTabA()
{
using ( YourDbContext context = new YourDbContext())
{
var tabAquery = from x in context.TabA
where ...
select x;
foreach( var item in tabAQuery)
{
item.LastModified = DateTime.Now;
if(???)
{
}
}
}
}
Now your changes will be applied the next time you call context.SaveChanges() from the calling method.

Building unit tests for MVC2 AsyncControllers

I'm considering re-rewriting some of my MVC controllers to be async controllers. I have working unit tests for these controllers, but I'm trying to understand how to maintain them in an async controller environment.
For example, currently I have an action like this:
public ContentResult Transaction()
{
do stuff...
return Content("result");
}
and my unit test basically looks like:
var result = controller.Transaction();
Assert.AreEqual("result", result.Content);
Ok, that's easy enough.
But when your controller changes to look like this:
public void TransactionAsync()
{
do stuff...
AsyncManager.Parameters["result"] = "result";
}
public ContentResult TransactionCompleted(string result)
{
return Content(result);
}
How do you suppose your unit tests should be built? You can of course invoke the async initiator method in your test method, but how do you get at the return value?
I haven't seen anything about this on Google...
Thanks for any ideas.
As with any async code, unit testing needs to be aware of thread signalling. .NET includes a type called AutoResetEvent which can block the test thread until an async operation has been completed:
public class MyAsyncController : Controller
{
public void TransactionAsync()
{
AsyncManager.Parameters["result"] = "result";
}
public ContentResult TransactionCompleted(string result)
{
return Content(result);
}
}
[TestFixture]
public class MyAsyncControllerTests
{
#region Fields
private AutoResetEvent trigger;
private MyAsyncController controller;
#endregion
#region Tests
[Test]
public void TestTransactionAsync()
{
controller = new MyAsyncController();
trigger = new AutoResetEvent(false);
// When the async manager has finished processing an async operation, trigger our AutoResetEvent to proceed.
controller.AsyncManager.Finished += (sender, ev) => trigger.Set();
controller.TransactionAsync();
trigger.WaitOne()
// Continue with asserts
}
#endregion
}
Hope that helps :)
I've written short AsyncController extension method that simplifies unit testing a bit.
static class AsyncControllerExtensions
{
public static void ExecuteAsync(this AsyncController asyncController, Action actionAsync, Action actionCompleted)
{
var trigger = new AutoResetEvent(false);
asyncController.AsyncManager.Finished += (sender, ev) =>
{
actionCompleted();
trigger.Set();
};
actionAsync();
trigger.WaitOne();
}
}
That way we can simply hide threading 'noise':
public class SampleAsyncController : AsyncController
{
public void SquareOfAsync(int number)
{
AsyncManager.OutstandingOperations.Increment();
// here goes asynchronous operation
new Thread(() =>
{
Thread.Sleep(100);
// do some async long operation like ...
// calculate square number
AsyncManager.Parameters["result"] = number * number;
// decrementing OutstandingOperations to value 0
// will execute Finished EventHandler on AsyncManager
AsyncManager.OutstandingOperations.Decrement();
}).Start();
}
public JsonResult SquareOfCompleted(int result)
{
return Json(result);
}
}
[TestFixture]
public class SampleAsyncControllerTests
{
[Test]
public void When_calling_square_of_it_should_return_square_number_of_input()
{
var controller = new SampleAsyncController();
var result = new JsonResult();
const int number = 5;
controller.ExecuteAsync(() => controller.SquareOfAsync(number),
() => result = controller.SquareOfCompleted((int)controller.AsyncManager.Parameters["result"]));
Assert.AreEqual((int)(result.Data), number * number);
}
}
If you want to know more I've written a blog post about how to Unit test ASP.NET MVC 3 asynchronous controllers using Machine.Specifications
Or if you want to check this code it's on a github