Laravel 6.12 seeding factory don't see states - laravel-6

As usual the project needed seeds.
And as usual I create a UserFactory, set it up, added to DatabasesSeeder and caught a error.
InvalidArgumentException : Unable to locate [models] state for [App\Models\User]
but the default factory (I mean $factory->define(User::class, function (Faker $faker)) is working fine
UserTableSeeder.php
use Illuminate\Database\Seeder;
use App\Models\User;
class UserTableSeeder extends Seeder
{
public function run()
{
factory(User::class, 50)->state('models')->create();
factory(User::class, 50)->create();
}
}
UserFactory.php
use App\Models\User;
use Faker\Generator as Faker;
use Illuminate\Support\Str;
$factory->define(User::class, function (Faker $faker) {
//everything works fine here
});
$factory->defineAs(User::class, 'models', function (Faker $faker) {
//exactly the same return except for a few string values
//but 'Unable to locate [models] state for [App\Models\User]'
});

Ok. I was able to reproduce the error in my enviroment. Here's the problem. You gave the name models to you factory but called it as if it was a state. $factory->defineAs (Not documented) does not define a factory with state but just give a name to your factory. Factory States and Named Factories (yours) are two different things. This is why you can't seed your database like it was a State Factory.
factory(User::class, 50)->state('models')->create();
If you want to use $factory->defineAs function, replace the above line with
factory(User::class,'models', 50)->create();
Or
(Recommended - Because it's well documented) If you still wish to be able to seed your database using ->state('models') (states), then change your UserFactory.php as follows
use App\Models\User;
use Faker\Generator as Faker;
use Illuminate\Support\Str;
$factory->define(User::class, function (Faker $faker) {
//everything works fine here
});
$factory->state(User::class, 'models', function (Faker $faker) {
//exactly the same return except for a few string values
//but 'Unable to locate [models] state for [App\Models\User]'
});
Remark: you now define your second factory with $factory->state and not $factory->defineAs.

Related

Express custom GET/POST parameter binding nestjs / routing-controllers

I have a Controller (nestjs / routing-controllers) and I'm passing a GET request the following way: /collect?t=My-name
t is actually a full name which I can't change.
Bellow im injecting #QueryParams() data: CollectData, Im looking for a way (like java strong and .net) to tell the controller that fullName is actually t.
Something like
export interface CollectData{
#PropertyName('t')
fullName: string
}
I'm expecting fullName to represent the t variable.
#JsonController()
export class CollectController {
#Get('/collect')
collect(#QueryParams() data: CollectData){
return data.fullName;
}
}
You could use some sort of solution using the class-transformer library and the ValidationPipe given by Nest (it also does transformations!) and have your CollectionData class (use a class so that the data can be serialized after transpiling, interfaces go away in JavaScript) look like this:
// CollectData.ts
export class CollectData{
#Expose({ name: 'fullName' })
t: string
}
//Collect.controller.ts
#Controller() // Changed from JSONController to Controller
export class CollectController {
#Get('/collect')
collect(#Query(new ValidationPipe({ tranform: true }) data: CollectData){ //Changed from QueryParams to Query
return data.fullName;
}
}
OR in your main.ts add the app.useGlobalPipes(new ValidationPipe({ tranform: true }) to set the validation pipe to run against all your incoming requests

Get authentication data inside of Constructor issue in Laravel5.3.19

I have upgrade Laravel from 4.2 to laravel5.3 but I can't access Authentication data inside of Constructor of Controller
I have as below Middleware but it never work for me
use App\Http\Controllers\BaseController;
use Closure;
use Illuminate\Contracts\Auth\Guard;
use Redirect;
use Auth;
use App\User;
class DashboardController extends BaseController
{
public $user;
public function __construct(Guard $guard, User $user)
{
$this->middleware(function ($request, $next) {
$this->user = Auth::user();
return $next($request);
});
//$this->userID = Auth::user()?Auth::user()->id:null;
dd($user);// Result attributes: []
dd($guard);
dd($this->user);
}
}
The result after DD()
dd($guard);
DD($this->user);
NULL
It will return Null when I dd user property.
This is to be expected. The reason you have to assign the user inside the middleware closure is because the session middleware hasn't run yet. So, the closure you have above won't actually be called until later in the execution process.
If you move the dd($this->user) to inside the middleware closure or in to your one of you route methods in that controller it should be working absolutely fine.
Also, just FYI, in your middleware closure you can get the user instance from the request i.e. $request->user() will give you the authenticated user.
Hope this help!

Set the default __toString() format per Carbon instance?

I retrieve dates from a database and have the option to pre-process them (via the Laravel framework (v5.2)). The dates or times can come in any particular format but for this example let's say Y-m-d.
I want to be able to access the date as a Carbon instance in the view — this would give me the flexibility to format the date however I please or do nothing with it and print as-is (with the default toString being the same as its original string format).
The issue is maintaining the default expected toString format at the top-level Carbon toString format.
According to the docs, you can use the ::setToStringFormat() method to change the default format of toString. It is possible to set it with the static method Carbon::setToStringFormat() but it also works as an instance method e.g. ($date = Carbon::now())->setToStringFormat('Y-m-d') - albeit this seems to behave identically to the static method.
So, is it possible to set the individual __toString() format for a date instance?
It would allow me to do the following:
public function getDateAttribute($value)
{
$date = Carbon::createFromFormat('Y-m-d', $value);
// $date->setToStringFormat('Y-m-d');
return $date; // prints in 'Y-m-d' format
}
In a view, I would then chain methods on the date, or print it as-is.
I had the same sort of issue and worked my way around it
First create a global serialization method for carbon dates (e.g. in the boot of the Laravel AppServiceProvider)
<?php
namespace App\Providers;
use Illuminate\Support\Carbon;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider {
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot() {
// ...
Carbon::serializeUsing(function (Carbon $carbon):string {
$format = $carbon->getSettings()['toStringFormat'] ?? 'Y-m-d\TH:i:s';
return $carbon->format($format);
});
// ...
}
// ...
}
Then set the 'toStringFormat' setting to the format you need
$someCarbonDate->settings([ 'toStringFormat' => 'Y-m-d' ]);
Carbon::serializeUsing will now check if the carbon being serialized has a toStringFormat and use that or it will fall back to some other format you define.
You could probably also create your own Carbon class and extend Carbon\Carbon or Illuminate\Support\Carbon (used by Laravel) and override the __toString method, but that creates some new challenges when used in combination with the casting Laravel does internally.
If you just want to set the default format for when rendering Blade templates you can use the Blade::stringable method.
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
// ...
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot() {
// ...
Blade::stringable(function(\Illuminate\Support\Carbon $dateTime) {
return $dateTime->format('d/m/Y H:i:s');
});
// ...
}
// ...
}
Any Illuminate\Support\Carbon instances should automatically be rendered with this format unless you choose otherwise.
For example...
{{ $user->created_at }} would now render as 23/07/2021 10:16:24 by default
{{ $user->created_at->toDateString() }} still works and would render as 23/07/2021
NOTE: You might need to run php artisan view:clear to clear any compiled views before this takes effect 🙂

Authentication views for Laravel 5.1

Laravel 5.1 has just been released, I would like to know how could I tell the AuthController to get the login & register view from a custom directory? the default is: resources/views/auth...
The trait AuthenticateAndRegisterUsers only has this:
trait AuthenticatesAndRegistersUsers
{
use AuthenticatesUsers, RegistersUsers {
AuthenticatesUsers::redirectPath insteadof RegistersUsers;
}
}
The code you're showing there only fills one function: it tells our trait to use the redirectPath from the AuthenticatesUsers trait rather than the one from RegistersUsers.
If you check inside the AuthenticatesUsers trait instead, you will find a getLogin() method. By default, this one is defined as
public function getLogin()
{
return view('auth.login');
}
All you have to do to get another view is then simply overwriting the function in your controller and returning another view. If you for some reason would like to load your views from a directory other than the standard resources/Views, you can do so by calling View::addLocation($path) (you'll find this defined in the Illuminate\View\FileViewFinder implementation of the Illuminate\View\ViewFinderInterface.
Also, please note that changing the auth views directory will do nothing to change the domain or similar. That is dependent on the function name (as per the definition of Route::Controller($uri, $controller, $names=[]). For more details on how routing works, I'd suggest just looking through Illuminate\Routing\Router.
for those who is using laravel 5.2, you only need to override property value of loginView
https://github.com/laravel/framework/blob/5.2/src/Illuminate/Foundation/Auth/AuthenticatesUsers.php
public function showLoginForm()
{
$view = property_exists($this, 'loginView')
? $this->loginView : 'auth.authenticate';
if (view()->exists($view)) {
return view($view);
}
return view('auth.login');
}
so to override the login view path, you only need to do this
class yourUserController {
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
.....
protected $loginView = 'your path';
}

How to access methods from a class based wordpress plugin?

I have a plugin which registers a post type, taxonomy and handles some business logic.
I went ahead and made my perfectly working plugin OO based and now it only works some of the time.
Its set-up like the following:
class Fruit {
public function __construct() {
add_action('init', array(&$this, 'init'));
}
public function init() {
$this->the_apple();
}
public function the_apple() {
return print $apple = 'my apple';
}
}
$fruit = new Fruit();
Then in taxonomy.php, withing the loop the following works:
$fruit->the_apple();
But once I use get_template_part with loop.php, this no longer works
$fruit->the_apple();
I get the following notice:
Notice: Undefined variable the_apple();
My fix was to use:
global $fruit;
and now it works all the time, just fyi about globals they get a bad rep. and there's namespacing issues, along with dumping everything into globals vs. using a registry.
In production i would never use the name $fruit, instead i would call it,
global $skylar_fruit;