elo

elo

Member Since 1 Year Ago

Experience Points 3,090
Experience Level 1

1,910 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 6
Lessons
Completed
Best Reply Awards 0
Best Reply
Awards
  • start-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-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-token Created with Sketch.

    Subscriber

    Earned if you are a paying Laracasts subscriber.

  • lifer-token Created with Sketch.

    Lifer

    Earned if you have a lifetime subscription to Laracasts.

  • lara-evanghelist 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.

21 Jul
1 day ago

elo left a reply on Image URL Works In Local Serve But Fails In Staging Environment

Very sorry guys. I forgot to copy the storage folder from public to public_html when I made updates and had to copy the entire app again to the staging server.

elo left a reply on Image URL Works In Local Serve But Fails In Staging Environment

It returns nothing

[staging]# php artisan --version
[staging]#

elo left a reply on Image URL Works In Local Serve But Fails In Staging Environment

I tried running the command via ssh but it does nothing. When I run php artisan it returns nothing but composer returns a list of the commands.

elo started a new conversation Working With Passport And Swagger For API Documentation

Hi guys, I am using swagger for the documentation of an API application built using Laravel 5.8. I am also using Passport for the API authentication and tried implementing it in the documentation.

When I try to authorize a user on swagger, I get the error here

auth errorTypeError: NetworkError when attempting to fetch resource.

Here's how I have set it up swagger up

In l5-swagger.php config file

/* Open API 3.0 support */
'passport' => [ // Unique name of security
    'type' => 'oauth2', // The type of the security scheme. Valid values are "basic", "apiKey" or "oauth2".
    'description' => 'Laravel passport oauth2 security.',
    'in' => 'header',
    'scheme' => 'https',
    'flows' => [
        "password" => [
            "authorizationUrl" => config('app.url') . '/oauth/authorize',
            "tokenUrl" => config('app.url') . '/oauth/token',
            "refreshUrl" => config('app.url') . '/token/refresh',
            "scopes" => []
        ],
    ],
],

In the controller I have the swagger code

/**
* @OA\Get(
*      path="/products/{product}",
*      tags={"Product"},
*      description="Gets specified product",
*      operationId="getProductById",
*      summary="Fetches a product by the product Id",
*      security={{"passport": {}}},
*      @OA\Parameter(...),
*      @OA\Response(...),
* )
*/

This is the image of swagger authorization screen

https://i.stack.imgur.com/aiYjs.png

I get the client_id & client_secret from the oauth_clients table.

What am I doing wrong?

elo started a new conversation Image URL Works In Local Serve But Fails In Staging Environment

Hi guys, I am working on an API application using Laravel 5.8 version. When a get request is made to the products api endpoint, I return a ProductResource collection which looks like this

public function toArray($request)
{
    return [
        'id'            => $this->id,
        'name'          => $this->name,
        'category'      => $this->category,
        'description'   => $this->description,
        'status'        => $this->status,
        'price'         => $this->price,
        'barrels'       => $this->barrels,
        'interest'      => $this->interest,
        'start'         => $this->start,
        'end'           => $this->end,
        'hidden'        => $this->hidden,
        'imageUrl'      => asset('storage/images/products/' . $this->image->name)
    ];
}

The challenge I am having is that on my local server clicking the returned imageUrl displays the correct image but in the staging environment, I get the default 404 not found page.

I created a symbolic link from public/storage to storage/app/public on my local server which i am developing on to store the actual image file before uploading the app file to the staging environment. A quick check of the storage/app/public/images/products in the staging environment shows the image file but I still cannot view it from my browser. What could be the possible reason for this behavior?

Here's a sample of the resource in both my local and staging environments

Local/development server

{
    "id": 17,
    "name": "test",
    "category": "test",
    "description": "test",
    "status": "test",
    "price": 10990,
    "barrels": 207736,
    "interest": 0.2,
    "start": "2019-07-25",
    "end": "2019-08-25",
    "hidden": 0,
    "imageUrl": "http://localhost:8000/storage/images/products/pramopro_test_17.jpeg"
  }

Staging server

{
    "id": 13,
    "name": "test prod",
    "category": "test prod category",
    "description": "test prod description",
    "status": "loading",
    "price": 10000,
    "barrels": 300000,
    "interest": 0.2,
    "start": "2019-07-22",
    "end": "2019-08-28",
    "hidden": 0,
    "imageUrl": "http://staging.pramopro.com/storage/images/products/pramopro_testprod_13.jpeg"
  }
19 Jul
3 days ago

elo left a reply on Email Verification Redirects To Login

My code just became cleaner. Thanks for the tip. I still don't know how to make the verificationUrl work or change it to use the login endpoint, any thoughts on that?

elo left a reply on Email Verification Redirects To Login

Interesting. Considering that I have an API endpoint set up for login too, how can I customize the verification link to redirect the user to the login API endpoint?

As for the use of events, I am not using the default RegisterController and have a customer AuthController that handles both registration and login. If I wanted to use events, what will I have to do?

elo started a new conversation Email Verification Redirects To Login

The goal I want to achieve is to send users a email verification notification when they register via an API endpoint. To do that, I have done the following

  1. Ensured the App\User implements Illuminate\Contracts\Auth\MustVerifyEmail contract
use Illuminate\Contracts\Auth\MustVerifyEmail;

class User extends Authenticatable implements MustVerifyEmail
{
    use HasApiTokens, Notifiable;

    ...
}
  1. User table has the email_verified_at column

  2. Set verify to true in web.php

Auth::routes(['verify' => true]);

  1. Send the notification in the register method of custom registeration controller AuthController like this
public function register(Request $request) {
    $user = User::create([
        'firstname' => $request->firstname,
        'lastname'  => $request->lastname,
        'username'  => $request->username,
        'password'  => bcrypt($request->password)
    ]);

    if ($user) {
        $user->sendEmailVerificationNotification();
    }
}

I get the email notification but the link redirects me to the login page. Why is this happening instead of actually verifying the email?

Please note that my users table does not have the email column, it uses a username column for storing emails instead.

18 Jul
4 days ago

elo left a reply on Sending Notification On Successful Events

What is the advantage of doing it this way compared to just creating a routeNotificationForMail method in the User model and returning the username inside it?

elo left a reply on Sending Notification On Successful Events

Boom! Fixed it by defining a routeNotificationForMail method in the User model and then return $this->username; inside the method like this

public function routeNotificationForMail($notification)
    {
        return $this->username;
    }

elo left a reply on Sending Notification On Successful Events

@johnbraun @snapey Thanks for pointing the fact that it's the user that needs to be notified. I have made that correction but still not able to get the notifications. I don't know if this is because my users table does not have an email field, the emails are store in the username field. Can this be the issue? Is there a way to work with the username field?

elo started a new conversation Sending Notification On Successful Events

I am working on an Laravel 5.8 API application that need to notify users when they successfully place an order. The order process works but I am not getting the email notification. Here's how I am going about it using mailtrap for demo purpose

MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=**************
MAIL_PASSWORD=**************
MAIL_ENCRYPTION=tls

In Order model I am using the notifiable trait

<?php

namespace App;

use App\User;
use App\Product;
use Illuminate\Notifications\Notifiable;

use Illuminate\Database\Eloquent\Model;

class Order extends Model
{
    use Notifiable;

    ...
}

Created the OrderSuccesful notification and using it in the OrderController store method like so

<?php

...

use App\Notifications\OrderSuccessful;

use App\Order;
use Illuminate\Http\Request;

class OrderController extends Controller
{
    public function store(Request $request, Product $product)
    {
        // create order
        $order = Order::create([
            'user_id'       => auth()->user()->id,
            'product_id'    => $product->id,
            'barrels'       => $request->barrels,
            'status'        => 'successful'
        ]);

        $user = auth()->user();
        
        // notify user of successful order
        $user->notify(new OrderSuccessful($order));

        return new OrderResource($order);
    }
}

Now when I make a successful order, I don't get a notification. Since I am using the notification for the first time, I am wondering what I have missed. Appreciate it if someone can point that out and tell me how to fix it.

17 Jul
5 days ago

elo left a reply on Unable To Send Mails And Gets Authentication Required Message

Finally resolved it. First the issue was that changes made for the mailing config in .env file were not being read by laravel yet so I ran php artisan config:cache and that did the trick.

elo left a reply on Unable To Send Mails And Gets Authentication Required Message

I removed Auth::routes(['verify' => true]) from api.php and added it to web.php, did a test and got a different error this time

Route [verification.resend] not defined

Ran the command php artisan route:list and can't find the route email/resend email/verify email/verify/{id} but if I keep Auth::routes(['verify' => true]) in api.php and remove it from web.php the routes can be found but I get the previous error

"message": "Expected response code 250 but got code "530", with message "530 5.7.1 Authentication required\r\n"", "exception": "Swift_TransportException",

elo left a reply on Display Image Saved In Storage Folder

Use asser helper. Wrap the path inside the asset helper like this asset('storage/...')

elo left a reply on Display Image Saved In Storage Folder

How are you retrieving the image?

elo started a new conversation Unable To Send Mails And Gets Authentication Required Message

I am trying send email verification links to user when they register but I get a message Authentication required and mail isn't sent. I tried using mailtrap for demo and sendgrid which I will be using in production but the message was the same. This is how I a going about it

After running composer require guzzlehttp/guzzle I updated my env file like this

# MAIL_DRIVER=smtp
# MAIL_HOST=smtp.mailtrap.io
# MAIL_PORT=2525
# MAIL_USERNAME=bd33392050425f
# MAIL_PASSWORD=b4b02dc514dfc1
# MAIL_ENCRYPTION=tls

MAIL_DRIVER=smtp
MAIL_HOST=smtp.sendgrid.net
MAIL_PORT=587
MAIL_USERNAME=sendgrid_username
MAIL_PASSWORD=sendgrid_password
MAIL_ENCRYPTION=tls

In the controller, I want to send the mail after a user is successfully created like this

...
use App\Mail\VerifyEmail;

...
use Illuminate\Support\Facades\Mail;

public function register(Request $request)
{
    // create and store new user record
    $user = User::create([
        'username'  => $request->username,
        'password'  => bcrypt($request->password)
    ]);

    // send user email verification link
    Mail::to($user->username)->send(new VerifyEmail());
}

VerifyMail.php

<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;

class VerifyEmail extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        $from = '[email protected]';
        $name = 'custom name';
        $subject = 'Welcome! Confirm Your Email';

        return $this->from($from, $name)
            ->subject($subject)
            ->view('auth.verify');
    }
}

Following the documentation for email verification https://laravel.com/docs/5.8/verification#verification-routing I added the Auth::routes(['verify' => true]) to api.php file like this

<?php

// Register routes for email verification
Auth::routes(['verify' => true]);

Route::prefix('v1')->group(function () {

    // protected routes
    Route::middleware('auth:api')->group(function () {

        Route::get('products', '[email protected]'); // get products

    });

});

Route::fallback(function () {
    return response()->json(['error' => 'Not Found'], 404);
});

Why am I getting the Authentication required error message and how can I fix it?

12 Jul
1 week ago

elo left a reply on Return Full Image Url In API Resource

Thanks for pointing that issue of having the public in the url out.

elo left a reply on Return Full Image Url In API Resource

Right, the productImages table has an id, product_id & name fields

elo left a reply on Return Full Image Url In API Resource

Moving to say a staging or production environment is the reason I am asking this question. For instance I have a staging environment staging.domain.com where I am pushing my code to so the team can have access to the API. How can I write my code so it builds the correct url? What did you mean by "keeping the id part of the path in database"?

elo started a new conversation Return Full Image Url In API Resource

I am working on a Laravel 5.8 API application and I want to pass an image attribute with the value as the full url of the image. So I have created a symbolic link from public/storage to storage/app/public by running the artisan command

php artisan storage:link

I am storing the image in my controller like this

if ($product = Product::create([
        'name'      => $request->name,
        'category'  => $request->category,
        'status'    => $request->status,
        'price'     => $request->price,
        'interest'  => $request->interest,
    ])) {
        // store the product image
        $file = $request->file('image');
        $destinationPath = "public/images/products";
        $filename = $product->name . '_' . $product->id . '.' . $file->extension();

        Storage::putFileAs($destinationPath, $file, $filename);

        ProductImage::create([
            'product_id'    => $product->id,
            'name'          => $filename
        ]);
    }

This is what the ProductResource looks like

return [
    'id'        => $this->id,
    'name'      => $this->name,
    'category'  => $this->category,
    'status'    => $this->status,
    'price'     => $this->price,
    'interest'  => $this->interest,
    'image'     => 'http://localhost:8000/api/v1/public/images/products/' . $this->image->name,
];

Reason why I want to return the full image path is so that the React application consuming the api can simply pass the image path inside the <img src="">

Is this proper way to do it?

08 Jul
2 weeks ago

elo left a reply on Return Single Related Resource In A Resource

Many thanks, like you said it is very simple and straight forward.

elo left a reply on Return Single Related Resource In A Resource

You are spot on with the user/product relationship

User.php

public function product()
{
   return $this->hasOne(Product::class);
}

Product.php

public function user()
{
   return $this->belongsTo(User::class);
}

elo started a new conversation Return Single Related Resource In A Resource

Returning a related resource collection is straight forward as seen here https://laravel.com/docs/5.8/eloquent-resources#writing-resources. So if I have a UserResource and a ProductResource, I can easily return a products collection inside the UserResource like this

return [
    'firstname' => $this->firstname,
    'lastname'  => $this->lastname,
    'username'  => $this->username,
    'products'  => ProductResource::collection($this->products),
];

What if I was dealing with product not products? How I would I return a single resource that isn't a collection?

return [
    'firstname' => $this->firstname,
    'lastname'  => $this->lastname,
    'username'  => $this->username,
    'product'  => ????
];
06 Jul
2 weeks ago

elo left a reply on Session Store Not Set On Request When Authenticating Via Socialite

That's very informative, never knew that. I no longer get that error but now when I try to calling it like this http://localhost:8000/api/v1/login/facebook I get sent to the default laravel login page instead of going to facebook. Keep in mind that I am trying to use socialite for api authentication.

05 Jul
2 weeks ago

elo started a new conversation Session Store Not Set On Request When Authenticating Via Socialite

I am building API endpoint with Laravel 5.8 using Passport and Socialite for authentication. API authentication with Passport works fine but I am getting a runtime exception error

Session store not set on request

when I try to authenticate using facebook. Here's how I have set up my code

API endpoints

Route::get('login/facebook', '[email protected]');

Route::get('login/facebook/callback', '[email protected]');

Controller methods

public function facebookRedirect()
{
    return Socialite::driver('facebook')->redirect();
}

public function facebookCallback()
{
    return Socialite::driver('facebook')->stateless()->user();
}

Added the facebook key to service.php file like this

'facebook' => [
    'client_id'     =>  env('FACEBOOK_CLIENT_ID'),
    'client_secret' => env('FACEBOOK_CLIENT_SECRET'),
    'redirect'      => env('FACEBOOK_CALLBACK_URL'),
],

How do I resolve this error?

elo left a reply on What Is The Proper Way To Handle API Redirection

I decided to create a get request for the authenticated user when the redirection is done from the frontend.

Thanks guys.

02 Jul
2 weeks ago

elo started a new conversation What Is The Proper Way To Handle API Redirection

Hey guys, I am working on a project that uses React for the frontend and Laravel for the API endpoints which I am responsible for.

The logic is to redirect users to the dashboard on successful registration or login. The dashboard will be displaying all user info except the password of course.

Here's how I have setup the registration and login API endpoints using Passport

api.php

Route::post('register', '[email protected]');

Route::post('login', '[email protected])

My BaseController methods are set up like this

public function register(Request $request)
{
    $validator = Validator::make($request->all(), [
        'firstname' => 'required',
        'lastname'  => 'required',
        'username'  => 'required|email',
        'password'  => 'required'
    ]);

    if ($validator->fails()) {
        return response()->json(['Error', $validator->errors()], 401);
    }

    $user = User::create([
        'firstname' => $request->firstname,
        'lastname'  => $request->lastname,
        'username'  => $request->username,
        'password'  => bcrypt($request->password)
    ]);

    $success['token'] = $user->createToken('Pramopro')->accessToken;

    return response()->json(['success' => $success, 'message' => 'You have successfully registered'], 200);
}

public function login() {
    if (Auth::attempt(['username' => request('username'), 'password' => request('password')])) {
        $user = Auth::user();
        $success['token'] = $user->createToken('Pramopro')->accessToken;

        return response()->json(['success' => $success, 'message' => 'You have succesfully signed in.'], 200);
    }
    else
    {
        return response()->json(['error' => 'Unauthorised'], 401);
    }
}

Both endpoints work fine and i get the token back.

My question is how do I set up the dashboard API so that on redirect the authenticated user details are sent in the response?

19 Jun
1 month ago

elo left a reply on Change Visitor Language Based On Location

@AURAWINDSURFING - I would to love to learn how this can be done. Can you point me to a place where I can learn this?

11 Jun
1 month ago

elo left a reply on Return Json Response For Only API 404 Error

@YEZAWHEIN - @yezawhein I just tried out this method but got the same result. I going to keep trying as I believe that it's achievable.

10 Jun
1 month ago

elo left a reply on Return Json Response For Only API 404 Error

@CALEX - Actually tried doing that but got the same error. Been at this for 2days now

elo left a reply on Return Json Response For Only API 404 Error

@YEZAWHEIN - It throws an error

Symfony\Component\Debug\Exception\FatalThrowableError thrown with message "Class 'App\Exceptions\Route' not found"

elo started a new conversation Return Json Response For Only API 404 Error

I have exposed the API of a laravel 5.7 application. My goal is to return json response for all API calls that results in a 404 error.

This is how I have gone about achieving my goal

I modified the app\Exceptions\Handler.php file like this

// Add this at the top after namespace
use Illuminate\Database\Eloquent\ModelNotFoundException;

// Edited the render method like this
public function render($request, Exception $exception)
{
    if ($exception instanceof ModelNotFoundException && $request->wantsJson()) {
        return response()->json(['error' => 'Book Not found'], 404);
    }

    return parent::render($request, $exception);
}

And add a fallback route to routes\api.php file like this

Route::fallback(function(){
    return response()->json(['message' => 'Page Not Found'], 404);
});

With this a call to a route that doesn't exist returns this {"message":"Page Not Found"} correctly but a call to localhost:8000/api/books/1 returns the default laravel 404 page which is not the behavior I am looking for.

If i remove && $request->wantsJson() from the render method, both calls made to localhost:8000/books/1 & localhost:8000/api/books/1 return {"error":"Book Not found"}. But this also is not what i want.

Target Behavior:

get localhost:8000/books/1 return default laravle 404 not found page

get localhost:8000/api/books/1 return json response

How can I achieve this?

04 Jun
1 month ago

elo left a reply on Display API Resource Response Data In A View

@CALEX - Worked like a charm chief. I owe you a drink wink Interesting stuff I need to learn some more

elo left a reply on Display API Resource Response Data In A View

@CALEX - Found the documentation [here] (https://laravel.com/api/5.7/Illuminate/Http/Request.html#method_wantsJson) Wonder why it says the request is undefined

elo left a reply on Display API Resource Response Data In A View

@CALEX - Couldn't find $request->wantsJson() in the 5.7 documentation. Tried the snippet but got the error message Undefined variable: request

elo left a reply on Display API Resource Response Data In A View

@CALEX - $request->wantsJson() that's something new to me. Educate me please, how is it used in this case? Let me search for it in the meantime

elo left a reply on Display API Resource Response Data In A View

@TRAY2 - My application isn't using vue right now. What I really want to do is return a books collection in my controller using the BookResource then display the books on the welcome page.

elo started a new conversation Display API Resource Response Data In A View

I have a simple bookstore laravel 5.7 app. I want to expose the app API also using laravel's api resources.

I am able to use the app features and also test the api endpoints on postman successfully but I am not convinced that way I have gone about it is the right way. Here is how I have gone about it

BookController

public function index()
{
    $books = Book::paginate(12);


    return view('welcome', compact('books'));
}

web.php

Route::get('/', '[email protected]');

api.php

Route::get('/books', function() {
    return BookResource::collection(Book::with('ratings')->get());
});

Is it possible to use the BookResource in my controller so that

  1. I can return the welcome view along with the data
  2. I can display data in the view
  3. My api.php routes can be formatted like this Route::get('book', '[email protected]')

Is this doable?

15 May
2 months ago

elo left a reply on Images Uploaded In Storage Not Accessible

@JACKL - Creating a php file in the public_html and attempting to access a route with the filename worked like magic. Everything worked fine after that. Basically it was something similar to what @andreich1980 suggested but without the need to create a route for it.

elo left a reply on Images Uploaded In Storage Not Accessible

@ROBSTAR - This particular client already purchased a domain name and the hosting with a preferred host so I had no input in that but I also learnt something new today on how symbolic links can be created without ssh on shared hosting.

elo left a reply on Images Uploaded In Storage Not Accessible

@ANDREICH1980 - As suggested, I created the route for test and add this code to it then called it but got an error symlink(): No such file or directory

route::get('/test', function () {
    symlink('/home2/raydacon/public_html/storage', '/home2/raydacon/raydaconcept/public_html/storage/app/public');
});

elo left a reply on Images Uploaded In Storage Not Accessible

@ANDREICH1980 - Is there a way I can create the symbolic link on shared hosting without ssh? Been waiting on the hosting support guys but no response yet.

elo started a new conversation Images Uploaded In Storage Not Accessible

In a laravel 5.6 project, I created a symbolic link using php artisan symboli:link cammand which then created a storage directory in my public folder on my development server. Everything seems to work fine on dev server but after deploying on shared hosting, image upload works fine and I can see the image in raydaconcept/storage/app/public/images/photos but the file is not in public_html/storage/images/photos.

When I copied an uploaded file from raydaconcept/storage/app/public/images/photos to public_html/storage/images/photos, I was able to display the picture on the site as I wanted.

How can I fix this so that my uploaded files show up in both places?

05 Oct
9 months ago

elo left a reply on ErrorException: Trying To Get Property 'id' Of Non-object

@tykus thanks. What eventually did was to get an existing user, authenticate the user and add a book before updating the book.

// Select an existing user randomly & authenticate the user.
        $user = User::all()->random();
        Passport::actingAs($user);

        // User adds a book
        $selectedBook = factory(Book::class)->create(['user_id' => $user->id]);

        // Update the book.
        $response = $this->json('PUT', '/api/books/'.$selectedBook->id, [
            'title'     => $this->faker->sentence(),
            'author'    => $this->faker->name()
        ]);

        $response->assertStatus(200);

elo started a new conversation ErrorException: Trying To Get Property 'id' Of Non-object

Recently I have been learning how to write unit test for my laravel apps and it's been interesting so far.

After many attempts, I finally wrote a test that updates a record but the strange thing is that sometimes the test passes and other times it fails. When the test fails, it throws the error

ErrorException: Trying to get property 'id' of non-object

The test in question is

public function testUpdateBookRecord()
    {
        // Select an existing user randomly & authenticate the user.
        $user = User::all()->random();
        Passport::actingAs($user);

        // Get any book belonging to the user.
        $selectedBook = Book::where('user_id', $user->id)->inRandomOrder()->first();

        // Update the book.
        $response = $this->json('PUT', '/api/books/'.$selectedBook->id, [
            'title'     => $this->faker->sentence(),
            'author'    => $this->faker->name()
        ]);

        $response->assertStatus(200);
    }

The controller function for updating a record is like this

public function update(Request $request, Book $book)
    {
        $validatedData = $request->validate([
            'title'     => 'required|unique:books',
            'author'    => 'required'
        ]);

        // Update book if the logged in user_id is the same as the book user_id
        if ($request->user()->id === $book->user_id) {
            $book->update($request->only(['title', 'author']));

            return new BookResource($book);
        } else {
            return response()->json(['error' => 'You do not have the permission for this operation'], 403);
        }
    }

The question is what is the reason for the test passing sometimes and then failing other times?

03 Oct
9 months ago

elo left a reply on Using Default UserFactory Inside Another Factory

@iyoworks Thanks for that answer. If i go this way, then in my test there will be no need to call the UserFactory since calling the BookFactory will create a user and assign the user_id. Then how will i go about checking authentication in my test? Using $response = $this->actingAs($user)->json.. will throw an error saying user is undefined.

elo started a new conversation Using Default UserFactory Inside Another Factory

I wrote a phpunit test to check that only an authenticated user with the same user id as a book's user id can update the book record but it failed.

public function test_onlyAuthenticatedUserCanUpdateBookSuccessfully()
    {
        $user = factory(User::class)->create();
        Passport::actingAs($user);

        $book = factory(Book::class)->create();

        dd($user, $book);

        // $response = $this->json('PUT', '/api/books/'.$book->id, [
        //         'id'    => $book->id,
        //         'title' => 'Updated book title',
        //         'author'=> 'New Guy'
        //     ]);

        // $response->assertStatus(201);
    }

While checking the dump, i discovered that the user id and the book's user_id are different

// Newly created user
#original: array:7 [
    "name" => "Prof. Norwood Erdman"
    "email" => "[email protected]"
    "updated_at" => "2018-10-03 14:11:20"
    "created_at" => "2018-10-03 14:11:20"
    "id" => 2
]

// Newly created book
#attributes: array:6 [
    "title" => "Quasi laudantium enim quas omnis."
    "author" => "Mr. Jayson Roob"
    "user_id" => 1
    "updated_at" => "2018-10-03 14:11:20"
    "created_at" => "2018-10-03 14:11:20"
    "id" => 3
]

This is because my BookFactory has been set up wrongly using hard coded user_id value

$factory->define(Book::class, function (Faker $faker) {
    return [
        'title'     => $faker->sentence,
        'author'    => $faker->name,
        'user_id'   => 1
    ];
});

How can I correct the BookFactory so that the user_id is set to the value of the created user? This is my UserFactory

$factory->define(App\User::class, function (Faker $faker) {
    return [
        'name' => $faker->name,
        'email' => $faker->unique()->safeEmail,
        'password' => '***************', // secret
        'remember_token' => str_random(10),
    ];
});
28 Sep
9 months ago

elo left a reply on Laravel PHPUnit Test Forbidden Error

@tykus Returned same error