willvincent

willvincent

Member Since 5 Years Ago

Central Minnesota

Experience Points
350,715
Total
Experience

0 experience to go until the next level!

In case you were wondering, you earn Laracasts experience when you:

  • Complete a lesson — 100pts
  • Create a forum thread — 50pts
  • Reply to a thread — 10pts
  • Leave a reply that is liked — 50pts
  • Receive a "Best Reply" award — 500pts
Lessons Completed
1635
Lessons
Completed
Best Reply Awards
342
Best Reply
Awards
  • start your engines Created with Sketch.

    Start Your Engines

    Earned once you have completed your first Laracasts lesson.

  • first-thousand Created with Sketch.

    First Thousand

    Earned once you have earned your first 1000 experience points.

  • 1-year Created with Sketch.

    One Year Member

    Earned when you have been with Laracasts for 1 year.

  • 2-years Created with Sketch.

    Two Year Member

    Earned when you have been with Laracasts for 2 years.

  • 3-years Created with Sketch.

    Three Year Member

    Earned when you have been with Laracasts for 3 years.

  • 4-years Created with Sketch.

    Four Year Member

    Earned when you have been with Laracasts for 4 years.

  • 5-years Created with Sketch.

    Five Year Member

    Earned when you have been with Laracasts for 5 years.

  • school-in-session Created with Sketch.

    School In Session

    Earned when at least one Laracasts series has been fully completed.

  • welcome-newcomer Created with Sketch.

    Welcome To The Community

    Earned after your first post on the Laracasts forum.

  • full-time-student Created with Sketch.

    Full Time Learner

    Earned once 100 Laracasts lessons have been completed.

  • pay-it-forward Created with Sketch.

    Pay It Forward

    Earned once you receive your first "Best Reply" award on the Laracasts forum.

  • subscriber Created with Sketch.

    Subscriber

    Earned if you are a paying Laracasts subscriber.

  • lifer Created with Sketch.

    Lifer

    Earned if you have a lifetime subscription to Laracasts.

  • evangelist Created with Sketch.

    Laracasts Evangelist

    Earned if you share a link to Laracasts on social media. Please email [email protected] with your username and post URL to be awarded this badge.

  • chatty-cathy Created with Sketch.

    Chatty Cathy

    Earned once you have achieved 500 forum replies.

  • lara-veteran Created with Sketch.

    Laracasts Veteran

    Earned once your experience points passes 100,000.

  • 10k-strong Created with Sketch.

    Ten Thousand Strong

    Earned once your experience points hits 10,000.

  • lara-master Created with Sketch.

    Laracasts Master

    Earned once 1000 Laracasts lessons have been completed.

  • laracasts-tutor Created with Sketch.

    Laracasts Tutor

    Earned once your "Best Reply" award count is 100 or more.

  • laracasts-sensei Created with Sketch.

    Laracasts Sensei

    Earned once your experience points passes 1 million.

  • top-50 Created with Sketch.

    Top 50

    Earned once your experience points ranks in the top 50 of all Laracasts users.

Level 50
350,715 XP
Mar
25
5 days ago
Activity icon

Replied to The GET Method Is Not Supported For This Route. Supported Methods: POST.

Add the method="POST" attribute to your form tag in the markup. This is basic html 101 stuff..

Mar
20
1 week ago
Activity icon

Replied to Need Help Converting Complex MySQL Query

What is a nested_insert

It's not a thing. What I was saying is you could create a stored procedure and name it that

Mar
10
2 weeks ago
Activity icon

Replied to Mastering Full Stack

It takes anywhere from 6-10 years to get great at something, depending on how often and how much you do it. Some estimate that it takes 10,000 hours to master something

https://zenhabits.net/the-only-way-to-become-amazingly-great-at-something/

Don't worry about how long it'll take, just get on with doing it.

Activity icon

Replied to Need Help Converting Complex MySQL Query

yea for something like this a custom nested_insert stored procedure would be nice anyway ...

Activity icon

Awarded Best Reply on Upgrade , Security Fixes

To get the latest bug/patch releases for the major version you're on: composer upgrade

To upgrade to 7, follow the upgrade guide

Activity icon

Replied to Need Help Converting Complex MySQL Query

@muzafferdede This has to be multiple queries though, it is updating existing records and inserting a new one.

Specifically what this code does is insert a new entry into a hierarchy/nested set in the DB as defined by the left/right values that define the traversal tree. Insertion of new items affects the left & right values of most of the other records in the table.

Activity icon

Replied to Parallel Data Processing And Writing To DB

I was thinking of running each task as a Job in queue and use sockets to track when all tasks are finished, but this feels unsafe to me, because a job might fail.

So... retry failed jobs?

A queue is absolutely the right solution here.

Mar
09
3 weeks ago
Activity icon

Replied to Need Help Converting Complex MySQL Query

Looks like it's complaining about the @myRight

Might be because it's multiple queries running through a DB::select too. No really familiar with the syntax here, but suspect that probably ought to be a DB::raw rather than a DB::select.

Activity icon

Replied to Grouping Abscence Results By Date

If you simply want to find the list of users who did not post within the time period, a whereNotIn would be the easiest option...

$postUsers = Post::whereBetween('date', [$first_date, $last_date])->pluck('user_id')->toArray();
$users = User::whereNotIn('id', $postUsers);

However if you really need to know the users that didn't post on each specific date in a range, that's a bit more involved. I'm not sure offhand how you'd do that in SQL, though I suspect it's possible. Very likely it'd be easier (albeit not more performant) to simply run one query per date in the range.

In that case the above queries would be basically the same, you'd just loop for each date and find users who did post, then use that to drive a whereNotIn clause to find the missing users for that date.

So long as your ranges aren't huge, and user list isn't massive, that should be performant enough for most things... and results could be cached so that the queries only need to be run once for each new day, basically.. Otherwise you're likely looking at having to generate some stored procedure(s) to get it done in the DB I think.

Activity icon

Replied to Upgrade , Security Fixes

To get the latest bug/patch releases for the major version you're on: composer upgrade

To upgrade to 7, follow the upgrade guide

Mar
06
3 weeks ago
Activity icon

Replied to Moment.js With Vue

fwiw, there are other as capable libraries as moment that are smaller... if you care about your js bundle size (which you should)

https://github.com/you-dont-need/You-Dont-Need-Momentjs

Activity icon

Replied to Return Response As A Download Using Spatie/Browsershot

just a plain file

Not sure what that means... as I said you'll probably have to examine the response to be sure you're handling it properly, I wouldn't necessarily expect my example to work without modifications.

Have you verified that the pdf is properly generated with the expected contents? Is it possible that the pdf generation process takes longer than the time to get the response somehow?

Might be better to simple return a link, and instead of the downloadFile method I shared expecting a data blob, populate the provided link from the response into the generated anchor tag.

Mar
05
3 weeks ago
Activity icon

Replied to Return Response As A Download Using Spatie/Browsershot

Since you're using ajax, basically, you need to inject an element into the dom, and automatically trigger a click on it to initiate the download.

A helper function like this is useful for that:

export default function downloadFile(data, { filename, mimeType } = {}) {
  const link = document.createElement('a');
  const blob = new Blob([data], {
      mimeType,
  });

  link.style.display = 'none';
  link.href = window.URL.createObjectURL(blob);
  link.download = filename;
  document.body.appendChild(link);
  link.click();

  // Some browsers may fail to download if the link is removed too quickly
  setTimeout(() => {
    document.body.removeChild(link);
  }, 100);
}

To use just pass your response data, the desired filename to send it as, and the appropriate mimetype to the function, it'll inject an anchor link to the dom, click it, and then 100ms later remove the link.

success: function(data) {
    downloadFile(data, {
      filename: `Your-desired-filename.pdf`,
      mimeType: 'application/pdf',
    });
},

You'll have to inspect what's actually getting sent back, not sure off hand the structure of the data that's returned... but that'll be close.

Activity icon

Replied to Need Help Converting Complex MySQL Query

Probably a good idea to lock yeah, given this query could touch every record in the table.

If I'm not mistaken all you should have to do to populalte those values into the query is to use replacements:


public function createCategory($parent, $node) {
  DB::raw('LOCK TABLE categories WRITE');
  DB::select('SELECT @myRight := rgt FROM categories
    WHERE name = ?;
    UPDATE categories SET rgt = rgt + 2 WHERE rgt > @myRight;
    UPDATE categories SET lft = lft + 2 WHERE lft > @myRight;
    INSERT INTO categories(name, lft, rgt) VALUES(?, @myRight + 1, @myRight + 2)',
    [$parent, $node]);
  DB::raw('UNLOCK TABLES');
}
Activity icon

Replied to Settings

You could certainly create a settings table where the id is a string rather than a serialized auto-incrementing id

Then you'd have stuff like:

id                      | value
------------------------|---------------------
can_withdraw            | 1
can_deposit             | 0

Though it seems like those settings, specifically, would be tied to individual users rather than system wide, but anyway..

This is what I've got in place for my current production application, the id is a string and the value is a json field so it can contain a string, a number, an array or an object as needed depending on the specific setting. Works rather nicely.

Am also doing a similar thing for permissions where the permission id is a machine-readable string value. This has the nice side-effect that the user_permission pivot is easy to see what permissions a given user has in the DB without having to dive into the permission table to see what an id is.. and I can simply fetch the ids of the current users permissions to see what they can/can't do without having to load all the perms too.

Activity icon

Replied to Story On How I Screwed Up (and I Need Advice On How To Fix)

Sounds like you're processing images on the fly, always.. instead you ought to process images on upload and write out new files with the processing applied, then serve those static files.

Not sure about glide, but I'm quite sure that intervention image (for example) will handle that.

and yes, if your server is underpowered, it'll always be slow and awful. :)

Activity icon

Replied to Should I Use MongoDB Instead Of MySQL In Laravel ? Is It Faster Or Not ?

Not enough background information to say, but the vast majority of the time.. No. Not a good idea or necessary whatsoever.

Stick to MySQL or Postgres.

Put another way -- if you don't know, or have a specific reason to use mongo, you very likely don't need it.

Mar
04
3 weeks ago
Activity icon

Replied to Working With Php In Javascript

You're trying to subtract a string from a string, that's not going to work... for obvious reasons. Thus the NaN output in your alert.

Population of the data from PHP into your script tag is behaving properly.. you're just not working with that data in a way that makes any kind of sense afterward :)

Mar
01
4 weeks ago
Feb
21
1 month ago
Activity icon

Replied to Any Suggestion For DataTables For Vue?

You're probably better off not displaying all 1000+ rows at once, but rather making use of paginated data and such. Haven't heard of the one you're using before, but another tip to speed up tables, or any large dataset in vue, is to limit the data you're working with to just what is actually necessary to build the display.

For example, if you are displaying a list of people, rather than throwing a whole user object, plus profile data, etc at the table, instead transform the data your backend returns and only include that which is actually necessary. Depending on the data this can potentially have a significant impact.

agGrid does basically everything you could ever want to do with a data table.. I'd recommend it: https://www.ag-grid.com/vuejs-grid/

Activity icon

Replied to How To Use (this.variable) Variable Inside The ForEach() Function ?

Fat Arrow functions are really the better option.. less typing, less having to keep track of references to foreign 'this' all over the place.. just.. better. :)

I find I tend to .map() more often than not too.. can't recall the last time I reached for .forEach() instead of .map()

Feb
20
1 month ago
Activity icon

Replied to Laravel Or Symfony

Symfony is generally for larger projects and Laravel for smaller ones

That statement is pure FUD.

Feb
19
1 month ago
Activity icon

Replied to SQL Query To Eloquent

Could be implemented with the query builder, but that'd largely just be replicating the raw queries you have here in a potentially more obtuse way.. but basically you'd do all the joins onto the root model query, and then just select the bits you actually care about, in this case most likely that'd be messages.*

Better solution though, probably would be to leverage something like this which apparently allows you to establish a "manyThrough" relationship through your existing many:many relationship.

The bonus there would be that you'd effectively just be able to do something like this afterward:

$user = User::where('id', 10)->with(['phoneMessages', 'emailMessages']);
Activity icon

Replied to Determine Whether User Is Allowed To Enter Route (Laravel, JWT, VueRouter)

The only way to guarantee validity is to make that api call.. so if it's really gotta be restricted to authenticated users, the api call should be considered necessary.

Activity icon

Replied to When To Use No Sql Databases In Laravel Projects

i will just put some models on scout and elastic that i want to full search

postgres' search options are really powerful, and there's a scout driver for it. Worth a look -- you can avoid the extra requirements of elastic which will simplify your infrastructure, and most likely reduce costs involved in running/hosting your application. :)

Activity icon

Replied to When To Use No Sql Databases In Laravel Projects

This is my opinion, from direct experience... so I'm going to present it as fact, even though it is technically opinion:

The only really good use for nosql is as a flexible [semi]permanent cache.. to offload precompiled complex query results that take a long time to run that you don't want to run in realtime and endure the slowness in production.

The unfortunate problem with noSql is it was sold as being great because it's schemaless! And so you can quickly develop whatever.. primarily in node.. and mongo in particular uses (a subset of) javascript to interact with the data, etc.. This is troublesome because data in an application almost always does have a fixed schema, it may evolve over time but it's still a defined thing.. and in fact many apps that use mongo use mongoose, which is effectively an orm providing rigid schema anyway...

Mongo is stupidly slow when you have huge amounts of data, and are, most especially, paginating that data, instead of just skipping x records it scans through all of them to get to the position you care about. If those records are large, that takes a massive amount of time.

The unstructured nature encourages terrible database design.. there are use cases, but they won't really apply to 99% of projects.. and I'd conservatively estimate that at least 50% of things built atop nosql would be better suited to sql, and in fact would likely be much more performant with a sql db.

Most people with little toy projects slapped together with express and backed by mongo never notice the crap performance that's very easily encountered because their data is miniscule and simplistic.

I migrated an application out of meteor (worst mess of crap I've ever dealt with) and mongo to adonis (the JS equivalent to laravel) + postgres.. and performance of the application increased massively.. night and day. It's possible the mongo DB could've been implemented in a more performant manner, but that would've ultimately just ended up using a NoSQL DB the same way one would normally use a SQL DB.. there was literally no point for that DB to have been used other than that was what meteor used.. and meteor was a terrible choice too.

In fact, I'd have just rewritten it in php with laravel, but getting adonis into the mix was enough of a chore, convincing anyone to let me use php just wasn't gonna happen.

Activity icon

Replied to Why In The Code Used Two For Loops I Mean Why It Isn't Only Loop With The Count ++ Inside It

Your implementation doesn't return a correct result. The original outputs 5, as expected.. but given the same input your implementation (after correcting syntax errors) outputs 2.

Activity icon

Replied to SELECT Query For Fetching Data

In the future you might want to be more specific and clear...

I have to write a query/stored procedure that fetches only the data from the users table that doesn't exist in the invoices table on that day.

My original answer did that. Fetch data from user table, not in the invoice table, on a specific date.

Activity icon

Replied to Determine Whether User Is Allowed To Enter Route (Laravel, JWT, VueRouter)

In my current production app the JWT token (and reset token) are stored in vuex, and persisted to localstorage. On any given request if the token has expired the response is a 401, which is caught by an axios interceptor and automatically triggers an attempt to refresh the token, assuming that succeeds the initial request refires, if token refresh fails user is kicked over to the login screen.

This particular app is backed by adonis, not laravel.. adonis is more or less laravel, in javascript.

Laravel does tokens a little differently by default, whereas adonis' token implementation has the notion of a long-lived refresh token out of the box in addition to the short-life jwt token. Those long-lived tokens can be invalidated at the server side. Not sure what it would take to implement the same sort of setup in laravel off hand, but it's worked quite nicely for my current app. I routinely see 401 responses when tokens expired, and like magic it all just rights itself by auto-refreshing, and then submitting the requests again.. seamless & invisible to users.

Activity icon

Replied to SELECT Query For Fetching Data

maybe there aren't any users not in the invoices table for the current date.. in that case no results would be the expected outcome

Activity icon

Replied to How To Avoid Duplicate Values At The Time Of Update Query Using If And Else Condition In Laravel Controller

It would be helpful if you reformatted your code so it's easier to read.

Activity icon

Replied to SELECT Query For Fetching Data

Right, as I said, it will select the users not in the invoices table.. as you asked.

Activity icon

Replied to Report Progress On Long Running Task

If you know how many iterations there are / what percentage of work is complete, you could pretty easily fire an event on completion of each chunk that does something.. presumably the goal is to update completion status in the UI, like a progress bar or something. So for that you'd probably want to have a JS powered progressbar that attaches to a websocket to listen for progress.. the event, when fired, would send out a status update over the socket, which then in turn would update the progress bar.

I have this sort of setup running in production with an MQTT server handling message deliver to clients. Everything in the api is async, so it was essential to set something up to keep users apprised of the status of their jobs.. basically it works like this:

User interacts with the UI an initiates a job, in many cases these involve numerous queries to and callbacks from our async backend api.. in many cases I also know how many callbacks to expect, so as each comes in I can easily calculate the completion percentage, and I can also do some rough ETA calculation based on how long it's taking each piece to arrive.

As each callback comes in, I fire off an MQTT message to a topic based on the job id of that job, which the client subscribed to when it kicked off said job.. messages are a fairly basic json payload containing progress, processing rate, eta, etc.. as each of those messages is received by the client application, it updates the appropriate job status progress bar in the UI. Upon completion, or error, those messages are also fired off to the same mqtt topic and the UI either shows completion and updates an element in the UI if applicable, or displays the appropriate error.

What I would suggest is firing off status info via some sort of websocket/messaging protocol, AND updating a DB record (or more likely redis) with progress information. That will allow you to reestablish things if the user triggers a job that will run for perhaps many hours, and then goes away, but comes back before completion.. then can then get resubscribed, and default to the last known status from the DB which ought to be very close to realtime..

It's not trivial.. but it's also not super complicated... just a handful of moving pieces to manage. Easiest option in laravel would be to fire an event on each loop, and put all the other logic for messaging/recording status in the event handler.

Activity icon

Replied to SELECT Query For Fetching Data

As it happens, I wrote a query using similar logic to what is necessary for this today..

You'll want to run something like this:

SELECT id FROM users
 WHERE NOT EXISTS (
    SELECT * FROM invoices
     WHERE invoice_date = ?
 )

Where that placeholder is the current date.. you may need to do some date casting or include a > and < range to capture a full day if the field is actually a datetime not just a date, but the where not exists is what you want to determine what from the full list of users does not exist in the invoices table.

Activity icon

Replied to Get "Grandparent" Relationship From Child

I have an app in production that is basically multi-tenant, users belong to organizations, and organizations exist in a hierarchy in the system. A user of any given organization can access content in their own organization and any descendants, but not content of their ancestors.. those ancestors however can of course access that organizations data as that organization is a decendant of the ancestor..

The way I modeled that in the DB so that I can quickly and painlessly find things any given user can access is that my organizations have both a parent id (the immediate parent organization) and an "ancestor tree" that is the ids of every organization higher in the hierarchy strung together with dashes..

ie:

org 1 has children 2 and 3

  • org 2 has children 4 5 6
  • org 3 has children 7 and 8
  • org 5 has children 9 and 10
  • org 9 has child 11
+ org1
  \
  + org 2
  |\
  | +-- org 4
  | +-- org 5
  | |\
  | | +--- org 9
  | | |\
  | | | +---- org 11
  | | +--- org 10
  | +-- org 6
  + org 3
   \
    +-- org 7
    +-- org 8

The db records look like this:

id     | parent_id | ancestor_tree
1      | null      | null     
2      | 1         | -1-
3      | 1         | -1-
4      | 2         | -1-2-
5      | 2         | -1-2-
6      | 1         | -1-
7      | 3         | -1-3-
8      | 3         | -1-3-
9      | 5         | -1-2-5-
10     | 5         | -1-2-5-
11     | 9         | -1-2-5-9-

So I can easily determine orgs that have content a user can access by querying where the org id is x, or the parent is x, or ancestor tree like %-x-%

It would also be trivial for any given item to look at the ancestor tree and determine it's grandparent, great grantparent, etc.

Thought I'd share because it can be considerably faster than querying several times to walk back through some relationships.

Feb
18
1 month ago
Activity icon

Replied to How To Learn To Read Code

@cameronasmith I love your profile image. I'm an old Amiga guy myself..

Activity icon

Replied to Changes To Route In Web.php Not Reflected On Shared Hosting

just crazy that you can't change a route in web.php without having to run a command in the terminal to get it to work correctly. Seems silly.

I mean.. you shouldn't have to, unless routes were already cached.. it seems most likely that this is a hosting issue, not a laravel issue.

Have you reached out to your host yet to ask why changes aren't being reflected in your live code as I suggested earlier? Do you have the ability to restart the php process, or webserver process? If they've got some opcode cache in place it may be failing to allow new code to be evaluated.. Have seen that before, but I haven't used any shared hosts in over a decade :D

Activity icon

Replied to Error On DB Where!

Sure you can brute force a crap query to run by jacking up the memory limit to ridiculous heights, but it's much better to actually fix the underlying issue rather than just, essentially, throwing money at the problem.

Activity icon

Replied to Laravel SPA (Sessions Vs JWT Authentication)

I would say that the main reason to build a SPA in the first place is so that the entire frontend is self-contained in what is effectively static files that can be served from wherever, preferably a cdn.. and that then talks to a load balanced multi-instanced backend so that it can scale, essentially to infinity.

Having spent the past several years with a decoupled application running a SPA on the frontend and a restful api backend with jwt, all sitting in front of another asyncronous backend.. I'm not terribly eager to build another SPA, I find there's just far too much duplicate logic needed for auth, permissions, routing, etc.. between the frontend app and the backend. Very much interested in how it's being done with InertiaJS, UI is still served up from the backend just like the good old days, but it's a full blown vue (or whatever) application, so only the data and components are loaded instead of full rendered pages.

The vast majority of things have no need for a SPA at all, and many still go that route anyway needlessly. It's more work and often not worth the effort.

Activity icon

Replied to Determine Whether User Is Allowed To Enter Route (Laravel, JWT, VueRouter)

I can't really think of a good reason to have a static page, that requires authentication, that isn't gonna hit the DB for anything

As for an endpoint.. just have something that verifies the user is authenticated and return true/false or return the user object or whatever.. doesn't seem like a difficult problem to solve

Activity icon

Replied to Update Record With Options

If that's the intent, then yes, definitely list of manufacturer id & name where id is the option value, and name is the option label.. probably still want some sort of typeahead filter solution on the list, even if it's a reasonably sized list in the 10s-50s of items, but if the list exceeds say 50 or so probably time to start thinking about autocomplete ajax lookups. Where you draw the line is debatable I guess

Activity icon

Replied to Why The Parameter For This Function Be The Key For The Array Posts ?

Ok, since he's using an array instead of a DB.. the array keys are effectively the model ids. so.. yeah.

What is the question here then?

Activity icon

Replied to Determine Whether User Is Allowed To Enter Route (Laravel, JWT, VueRouter)

@sunedall not if you've properly included validation on the backend ... this is the fundamental drawback of SPAs, you cannot avoid duplicate logic between the front/backend for routing and authentication..

But whatever, always always ALWAYS do validation of everything on the backend. client-side validation should be considered at best a noise filter, and/or just the preliminary line of defense. Expect that anything and everything can and will be changed in javascript, and implement backend protections accordingly.

Activity icon

Replied to Elocuent Newbe Question

Seems like my answer more directly answered the original question... but.. ok.

Activity icon

Replied to Update Record With Options

Seems that the ask is a bit unclear here, perhaps @chron can clarify some.

It sounds to me as if the question is regarding handling the update request for an existing record, to change a relationship value from one id to another.. If that's the case, other than validating that new id exists in the DB I don't see what further checks would really be necessary, and indeed what fetching all and looping would accomplish.

But, maybe as it's not clear, I'm just not understanding the question :)

Activity icon

Replied to Changes To Route In Web.php Not Reflected On Shared Hosting

Nah, you could just as well move the artisan calls into a controller.

Activity icon

Replied to Import CSV

Carbon::createFromFormat('d/m/Y H:i', $csv_date_field);

No problem at all.

Activity icon

Replied to Why The Parameter For This Function Be The Key For The Array Posts ?

Agree with Snapey, this looks utterly useless..

Activity icon

Replied to Changes To Route In Web.php Not Reflected On Shared Hosting

If you are unable to run artisan commands, you may want to consider adding a route that allows you to do some basic cache clearing/etc.

Of course if the routes are already cached, adding a new route isn't going to be as easily accomplished.. in any case, good reason to not use shared hosting.

Could be your shared host is running some sort of opcode cache, so even if laravel isn't writing a cache file, file changes maybe aren't getting picked up by the php process..? Might be best to reach out to support with your host and ask them why changes to your codebase and not being reflected in what is being served.

Feb
17
1 month ago
Activity icon

Replied to Nested Relationship With GroupBy And Count

Sometimes, this is likely one of those times, the best thing to do is run raw DB queries with the necessary joins/etc rather than trying to jump through a bunch of hoops just to use eloquent to fetch something that would otherwise be fairly straightforward.

Alternately, if you start from the raw queries, it's also usually easier to back into an eloquent/query builder implementation... though that's probably not necessary.