Pinball: The Man Who Saved the Game (Trailer)

https://theawesomer.com/photos/2023/02/pinball_the_man_who_saved_the_game_t.jpg

Pinball: The Man Who Saved the Game (Trailer)

Link

This movie dramatizes the story of Roger Sharpe, an NYC journalist who escapes from his stress by playing pinball, only to realize that the game is still illegal in the city. In 1976, he helped mount a campaign to overturn the 34-year ban and prove that pinball is a game of skill, not a game of chance. In theaters 3.17.23.

The Awesomer

When to use Laravel global scopes

https://hashnode.com/utility/r?url=https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1676907059595%2Fd3de6e98-b36d-4d65-b56b-50a8993b4fff.png%3Fw%3D1200%26auto%3Dcompress%2Cformat%26format%3Dwebp%26fm%3Dpng

Laravel global scopes are great, but I don’t see them used a lot. Instead, I see a lot of local scopes being used to achieve the same thing. With proper implementation of global scopes, the code and security would be greatly improved. Let me illustrate this with a simple example.

The local scope way

In our codebase, we have a model Transaction that stores transactions for our users. If we want to get the transaction for a logged-in user from the database, we could do it like this:

$transactions = Transaction::where('user_id', auth()->id())->get();

Since we would use this a lot throughout the codebase, it would make sense to create a local scope in the Transaction model like this:


namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class Transaction extends Model
{
    

    public function scopeForLoggedInUser($query): void
    {
        $query->where('user_id', auth()->id());
    }
}

With this local scope, we can make the query like this:

$transactions = Transaction::forLoggedInUser()->get();

This is a nice DRY (Don’t Repeat Yourself) refactor that cleans it up a little.

A question you should ask yourself

Local scopes are awesome, I use them where I can to keep the code DRY. But I learned to ask myself this question when I create a local scope: “Will the majority of the queries for this model use this local scope”.

If the answer is no, keep the local scope. It makes a lot of sense to use it.

When the answer is yes

This would be the point when considering a global scope. A global scope is always applied to all queries of a given model. You can create a global scope simply by creating a class that implements Illuminate\Database\Eloquent\Scope.

<?php

namespace App\Models\Scopes;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Scope;

class TransactionsForLoggedInUserScope implements Scope
{

    public function apply(Builder $builder, Model $model)
    {
        $builder->where('user_id', auth()->id());
    }
}

After that, you should let your model be aware of the global scope:

<?php

namespace App\Models;

use App\Models\Scopes\TransactionsForLoggedInUserScope;
use Illuminate\Database\Eloquent\Model;

class Transaction extends Model
{
    

    protected static function booted(): void
    {
        static::addGlobalScope(new TransactionsForLoggedInUserScope());
    }
}

If you would now get all the transactions, it will only return the transactions of the logged-in user.

Transaction::all();

Removing a global scope

There are some scenarios thinkable where you want to create a Transaction query without the global scope applied. For example, in an admin overview or for some global statistic calculations. This can be done by using the withoutGlobalScope method:

Transaction::withoutGlobalScope(TransactionsForLoggedInUserScope::class)->get();

Anonymous Global Scopes

There is also a way to create a global scope without the use of an extra file. Instead of pointing to the TransactionsForLoggedInUserScope class, you can include the query like this:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Transaction extends Model
{
    

    protected static function booted(): void
    {
        static::addGlobalScope('for_logged_in_users', function (Builder $builder) {
            $builder->where('user_id', auth()->id());
        });
    }
}

Personally, I don’t like anonymous global scopes since it can bloat your model if the query is a bit complex. To be consistent throughout the entire codebase, I always tend to use the external file global scopes, even if the query is as simple as in our example.

The downside of global scopes

I won’t lie to you, if you’re working on a codebase with global scopes and are not aware of them, you might fall into situations where nothing makes sense anymore. It made me question my career choices one (very bad) day 😂. You will get totally unexpected results when tinkering. If this has happened once, you’ve learned that it is good to have the withoutGlobalScopes method in your tool belt while working in a codebase you’re not quite familiar with.

Security

If the security of your app relies on a global scope, it’s dangerous when you or a fellow developer will make changes to it in the future. Imagine in our example that someone would remove or change the global scope. Then all results for a user’s transactions would be completely faulty! This is why it’s really important to implement tests for global scopes, so this can’t happen. A typical (PEST) test for our example would look like this:

it("should only get the transactions for the logged-in user", function (){
    $user = User::factory()->create();
    $otherUser = User::factory()->create();

    $transaction_1 = Transaction::factory()->create(['user_id' => $user->id]);
    $transaction_2 = Transaction::factory()->create(['user_id' => $otherUser->id]);

    $this->actingAs($user);
    expect(Transaction::all())->toHaveCount(1)
        ->and($transaction_1->is(Transaction::first()));
});

Laravel News Links

NEW Primary Arms 3-18×44 & 4.5-27×56 FFP GLx Rifle Scopes Ready For Pre-Order

https://www.thefirearmblog.com/blog/wp-content/uploads/2023/02/PA-GLX-3-18X44F-ATHENA_04-180×180.jpg

GLx Rifle Scopes from Primary ArmsIf you’ve been visiting TFB regularly, you’ve probably noticed that Primary Arms has been busy releasing a number of new products this winter. We’ve recently announced new binoculars, a 1-6x LPVO optic, pistol red dot sights, and a 5x prism sight. Primary Arms has just announced the pre-order status for their new First Focal Plane […]

Read More …

The post NEW Primary Arms 3-18×44 & 4.5-27×56 FFP GLx Rifle Scopes Ready For Pre-Order appeared first on The Firearm Blog.

The Firearm Blog

Jesus Decimates Enrollment At Galilee’s School For The Blind

https://media.babylonbee.com/articles/63f4fb283283363f4fb2832834.jpg

CAPERNAUM — Town officials are concerned after receiving multiple complaints from faculty at Galilee’s School for the Blind this week after Jesus of Nazareth apparently went on a healing spree and decimated the school’s enrollment.

“We were set to have an all-time high in our number of students enrolled,” said Rabbi Ananias Ben Josef, administrator of the school. “Come to find out, this carpenter — from that Nazareth ghetto of all places — strolled through Capernaum and started healing blind people left and right! We’ve got less than half of our original enrollment now! How am I supposed to pay overhead costs when I have hardly any students?”

Witnesses throughout the town said Jesus arrived with his group of disciples late in the morning at the beginning of the week and quickly drew a large crowd. “He walked in, started mingling with some of the regular people who hang out in the market, and not long after that, we all started hearing somebody start shouting, ‘I can see! I can see!'” said one man who was present in the marketplace when the healings began. “Others started bringing more sick and blind people, and things just snowballed from there.”

The school was reportedly looking into taking legal action against Jesus for causing financial harm to the institution, but there is no law against healing blind people unless it takes place on the Sabbath.

At publishing time, Jesus and His disciples had reportedly moved on to another town, with rumored plans in place to set people free from problems even more serious than blindness.


This man is under arrest – for MANSPLAINING!

Subscribe to our YouTube channel for more guffaw-inducing chucklefests!

Babylon Bee

Chrome 110 will automatically discard background tabs. Here’s how to stop it.

https://cdn.arstechnica.net/wp-content/uploads/2023/02/PerformanceControls_Header.width-1000.format-webp-760×380.webp

Chrome 110 will automatically discard background tabs. Here’s how to stop it.

Google

Heads up, everybody: Chrome will start doing stuff to your permanently open tabs. Chrome version 110 is rolling out now, and on Windows, macOS, and Linux, the release comes with the new “Memory Saver” feature that will be automatically enabled. We first wrote about this when it hit the Chrome nightly build “Canary Channel” in December, but now the feature is rolling out to everyone.

Chrome has a reputation for gobbling up RAM, and Google seems to think the best way to combat that is to automatically shut down your tabs when they are “inactive.” Google’s explanation of the feature says, “When a tab is discarded, its title and favicon still appear in the tab strip but the page itself is gone, exactly as if the tab had been closed normally. If the user revisits that tab, the page will be reloaded automatically.” Google says this technique will reduce Chrome’s memory usage by “up to 40 percent,” which sounds great, as long as it doesn’t break anything or cause users to lose the state of their page.

As a support page outlines, Google has some use cases excluded from this feature:

Some settings and activities on your computer may prevent tab deactivation.

  • Active audio or video (playback or calls)
  • Screen share
  • Page notifications
  • Active downloads
  • Partially filled forms
  • Connected devices (USB or Bluetooth)
  • The ‘chrome://discards/’ page will let you discard a tab manually for testing purposes.


    Ron Amadeo

  • I have no earthly idea what this graph is trying to communicate. You can click on the little balls and see various page details, though.


    Ron Amadeo

  • Look at it go! Here’s what the graph does when I open a new tab in another window and load Feedly.


    Ron Amadeo

You can take a peek at how all this works by typing “chrome://discards” into the address bar, which will bring up the developer UI to control the new tab discard feature. The “discards” tab will show you the state of all your tabs, and the right “actions” column contains an “urgent discard” link, allowing you manually discard any tab for testing purposes. After blowing up some of your favorite sites to see how they react, I highly recommend checking out the “Graph” tab here (there’s a gif in the above gallery), which is an association graph of processes and tabs that animates and moves around while you use Chrome.

You can try to divine Chrome’s tab discard behavior from this page. Visible foreground tabs cannot be discarded, even manually—you have to click over to some other tab, put a window in front of Chrome, or minimize Chrome to discard a tab. Presumably, that’s how the automatic discard feature works, too. Pages that have a serious unsaved state could be a real problem: if you dump a bunch of text into WordPress and try to close the tab with the normal close button, instead of closing, you’ll get a pop-up about unsaved changes, asking if you want to leave the site and potentially saving you from losing a bunch of work. If you use Chrome’s new tab discard feature, Chrome will trash your unsaved text like it was nothing. Some sites like Gmail deal with this well by following Google’s recommendations and auto-saving your draft text when the tab is sent to the background.

How to turn it off

  • If a tab gets shut down, you’ll see this message when you go back to it.

  • The new “Performance” settings and how to get to them.

The good news is that you can control all this. The consumer controls for Memory Saver live at ‘chrome://settings/performance,’ or, for the UI-inclined, hit the menu, then “More tools,” then “Performance.” You can turn off the feature entirely or add sites to a list called “always keep these sites active.” Google has detailed instructions for how the exclusion parsing works on the support page, but it supports everything you would expect, like subdirectories, wildcards, and specific subdomains. Personally, I need to add the Ars Technica WordPress instance because possibly losing unsaved article text is every writer’s nightmare.

Besides the memory-saving feature, this version of Chrome is also coming with an “Energy Saver” mode for laptops, where if you’re low on battery, it will throttle tab power usage by lowering video and scrolling frame rates. Controls for that feature will be in the same “performance” tab.

Ars Technica – All content