cwray-tech

cwray-tech

Owner/developer at Soltech LLC

Member Since 1 Year Ago

Pasco, WA

Experience Points
27,110
Total
Experience

2,890 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
252
Lessons
Completed
Best Reply Awards
0
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 6
27,110 XP
Oct
28
2 days ago
Activity icon

Replied to How To Create Sitemap For +30,000 Records.

Hi @refojunior I wrote a tutorial on how to do this on my website: https://chriswray.dev/posts/how-to-create-a-sitemap-in-laravel-for-a-website-that-contains-thousands-of-records

Feel free to check it out and let me know if that helps you!

Activity icon

Replied to How To Create Sitemap For +30,000 Records.

Hey @refojunior for sure! I will write a tutorial on how I did this, then send a link to you today. It is working well. I used the recommended way by @jlrdw but I will write more in detail how this is built in the tutorial.

Oct
15
2 weeks ago
Activity icon

Replied to Why Actions In Laravel 8?

Thanks, guys for all the responses and discussion! It was awesome seeing this kind of discussion in real-time! I also think I got a good understanding of the differences.

Activity icon

Replied to Why Actions In Laravel 8?

@sinnbeck Will do. Thanks!!

Activity icon

Started a new Conversation Why Actions In Laravel 8?

So, I was starting on a new app built on Laravel 8 and installed Jetstream, but one thing I am wondering is why do Fortify and Jetstream use Actions versus Controllers?

Should I be using Actions for my app, or is it still recommended to use Controllers for routes/functionality? Would love your input!

Sep
28
1 month ago
Activity icon

Replied to A Website Builder In Laravel?

@automica for sure! I agree. He wants to target his primary market specifically and make it really easy for them to create and manage their own sites.

Do you have anything to add regarding the question of custom domains?

Activity icon

Started a new Conversation A Website Builder In Laravel?

A friend of mine reached out to me last week with an idea he had for a website building platform kind of like Wix, but more simple.

Is this achievable with Laravel? Primarily, I am concerned about custom domains. Obviously, we would need to let users add custom domains for their websites, and I am thinking about the ease of doing that with Laravel.

Sep
14
1 month ago
Activity icon

Replied to My Images Are Visible On Local Server But Not On Hosting's Server

Have you run php artisan storage:link on your hosting server? In order to view files in your storage directory, you must link the storage with the public directory.

Activity icon

Replied to Is There A Way To Group Inputs And Validate Them As One Input?

Yes, @chron first you need to concatenate the three input's values, I believe, then validate the returned value as a date.

Activity icon

Replied to Open Source Laravel Projects For Learning?

I just made my project's code public on Github for code review and learning purposes. You can check it out: https://github.com/cwray-tech/myjourney.page

Activity icon

Replied to Lumen Or Laravel For API Development?

Thank you! Route model binding is not supported? That seems weird?

Activity icon

Replied to Using Vue With Laravel

I think that you can still use Vue Js the old way, but this is Laravels updated way to provide authentication I guess.

Activity icon

Replied to Using Vue With Laravel

Well, from looking at the new documentation, you need to install Laravel Jetstream, and go with Inertia.js for the js. This way you can use single file Vue components in your application: https://jetstream.laravel.com/1.x/introduction.html#inertia-js-vue

Activity icon

Started a new Conversation Lumen Or Laravel For API Development?

Would love input on using Lumen or Laravel for a pure API application? I want to build an app that will integrate with a Nuxtjs frontend so I only want to build an API.

One thing I noticed is that the Lumen website seems a little behind the main Laravel site. Is this because it is less developed, or is this just styling?

Thank you!

Aug
18
2 months ago
Activity icon

Replied to Mirroring Storage Directories On Same Server, Two Sites.

@sinnbeck thank you! I am using Envoyer to deploy them both. Do you know if that would be possible still, since envoyer sets up a symlink from the current deployment to the storage directory? Would I just add another symlink from the storage to the other storage directory?

Activity icon

Started a new Conversation Mirroring Storage Directories On Same Server, Two Sites.

I have a development site for beta testing, and a live production site on the same server. I would like to be able to mirror the storage directory for images that are uploaded by users on the development site to be available on the live site, and vise versa.

Can anyone point me to some resources/ tutorials on how to do this? Thank you!

Aug
11
2 months ago
Activity icon

Started a new Conversation Best Way To Optimize Images

I am considering implementing uploadcare into my project, but I am a little hesitant due to the cost. Is it worth it?

Another option is using the Spatie Image optimizer: https://github.com/spatie/image-optimizer#optimization-tools

If I do use the optimizer, is the best way to optimize images when they are being stored? If so, would it be best to create a job for this?

Aug
03
2 months ago
Activity icon

Awarded Best Reply on How To Delete Images From Public Disk When Deleting Item.

I found the issue to this. I was doing this correct, but I had a function to get the picture attribute which returned the whole path for views. As soon as I updated that, the pictures deleted correctly.

Activity icon

Replied to How To Delete Images From Public Disk When Deleting Item.

I found the issue to this. I was doing this correct, but I had a function to get the picture attribute which returned the whole path for views. As soon as I updated that, the pictures deleted correctly.

Activity icon

Started a new Conversation How To Delete Images From Public Disk When Deleting Item.

I am trying to delete an items image whenever the item is deleted and I am wondering how to do this correctly. In my delete function of the controller, I am using the Storage class to delete the picture like so, before I delete the item:

public function destroy( Journey $journey)
    {
        $this->authorize('delete', $journey);
        Storage::disk('public')->delete($journey->picture);
        $journey->delete();

        return redirect('/dashboard/journeys')->with('status', 'Journey was successfully deleted.');
    }

From the Laravel Docs, this seems like the way to do it, but when testing, the image is not deleted, but I am not getting any errors either.

Jul
07
3 months ago
Activity icon

Replied to Passing Props To Vue Component

@chizpon If you are trying to build a chart and the data is sensitive, then I would recommend to only pass the data that you want your users to see. You can do an http request in the controller, get only the data you are wanting, then pass only that to the vue component.

View more info about http requests here: https://laravel.com/docs/7.x/http-client

Jul
02
3 months ago
Activity icon

Started a new Conversation Permissions For Storage Directory

I am having an issue where I can only run artisan commands like cache:config from sudo in order for the command to work. I am getting an error whenever I try to just run artisan config:cache due to permission settings on the server.

How do I give myself permissions to do this on the live server?

Jun
13
4 months ago
Activity icon

Replied to How To Create Sitemap For +30,000 Records.

@jlrdw Could I use route model binding for this in order to not have to create routes for each letter? I am guessing yes..

Activity icon

Replied to How To Create Sitemap For +30,000 Records.

@bobbybouwmann yes, I tried the Spatie package, but unfortunately there are just too many records on the site. I think I will use the a, b, c answer with lazy collections. Thanks!

Activity icon

Replied to How To Create Sitemap For +30,000 Records.

That is a great idea, @jlrdw Thanks!

Activity icon

Started a new Conversation How To Create Sitemap For +30,000 Records.

I am creating a manual sitemap for the website- https://www.nurserypeople.com/. I have a sitemap controller and it generates a xml sitemap for pages on the site based on records in the database.

The only issue is that one of my tables for plants, has over 30,000 records in it, and I can only call a couple thousand before I run out of memory.

Is there any way to build this out on one page, or is the only option doing something like /plants/first.xml /plants/second.xml and splitting the records out that way?

Jun
09
4 months ago
Activity icon

Replied to Best Practice For Checking "capabilities" Instead Of "permissions"?

I'm not sure why you would want to do this.. It seems like to me that you want to make sure something is possible before ever letting a user try to do something anyways. That being said, you can surround functions with try, catch exceptions so that you can try to do something, and catch the exception if you can't. I wouldn't recommend doing this though. It is a great idea to use try- catches, but only on methods that you know exist.

Activity icon

Started a new Conversation Mobile App API: New Lumen Project, Or Use Existing Laravel Project?

Considering building a small mobile app for our website- nurserypeople.com.

I want to use the existing database(obviously), and a lot of the functionality will be the same, but I am wondering if it would be best to build a separate backend for the mobile api, for speed and separation of concerns. Would this be the best route to go? The mobile backend would be built on lumen.

Another question I have is for user authentication, will the application key need to be the same if I want to authenticate users through the api as well?

May
07
5 months ago
Activity icon

Commented on Building Data-Tables With Livewire

@calebporzio thanks so much for this. I was planning to go with a Vue SPA but after this, I would really like to go this route. Anything on the url question yet?

May
06
5 months ago
Activity icon

Replied to Order By Attribute From A Many-to-one Relationship

@michaloravec thank you.. When I do it that way it says column not found, because it isn't a column in the company db.

Activity icon

Started a new Conversation Order By Attribute From A Many-to-one Relationship

How would I perform an order by statement with an attribute of an item that is generated from a many to one relationship?

The model is a company, and each company has many reviews. Each company has a review attribute which is the average of all of the reviews ratings for the company.

I am trying to sort by top-rated companies, and would prefer not adding an extra column for the rating attribute in the companies table.

May
05
5 months ago
Activity icon

Replied to Top Rated Filter Not Working Properly.

@bugsysha if you aren't going to provide any real input, then why don't you stop? Appreciate it!

Activity icon

Replied to Top Rated Filter Not Working Properly.

Hey @bugsysha I think I figured it out. I was filtering by top-rated but my method is actually popular. If I filter by popular, I am getting what I was looking for.

Now, I am getting a column not found error because I am ordering by a attribute that comes from a relationship.

Activity icon

Replied to Top Rated Filter Not Working Properly.

@bugsysha

<?php

namespace App\Filters;

use Illuminate\Http\Request;

abstract class Filters
{
    protected $request,  $builder;

    protected $filters = [];

    public function __construct(Request $request)
    {
        $this->request = $request;
    }

    public function apply($builder)
    {
        $this->builder = $builder;

        foreach ($this->getFilters() as $filter => $value){
            if (method_exists($this, $filter)){
                $this->$filter($value);
            }
        }
        return $this->builder;
    }

    public function getFilters()
    {
        return array_filter($this->request->only($this->filters));
    }

}

Activity icon

Replied to Alternative To Algolia Search In Laravel

@iljido okay, well, I would probably need to see the errors to tell you anymore. If it is giving you errors, search them up in google. (:

Activity icon

Replied to Alternative To Algolia Search In Laravel

Okay, did you use Search in your Thread model, and import your index to algolia?

Activity icon

Replied to Top Rated Filter Not Working Properly.

Here is a better picture of the companycontroller:

<?php

namespace App\Http\Controllers;

use App\Filters\CompanyFilters;
use Auth;
use App\Company;
use Illuminate\Http\Request;


class CompanyController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth')->only(['store', 'create', 'edit', 'update', 'destroy']);
    }

    public function index(CompanyFilters $filters)
    {
        if($filters){
            $companies = Company::filter($filters)->paginate(20);
            return view('companies.index', [
                'companies' => $companies
            ]);
        }
        $companies = Company::latest()->where('is_published', true)
            ->orderBy('is_featured', 'desc')
            ->paginate(20);

        return view('companies.index', [
            'companies' => $companies,
        ]);
    }
}
Activity icon

Replied to Top Rated Filter Not Working Properly.

@bugsysha I did not show the whole company controller, but what part are you saying that I did not do things correctly?

Activity icon

Replied to Alternative To Algolia Search In Laravel

Did you add your algolia id and key to the env file?

Activity icon

Replied to Where To Put My Flash-messages (design Question)

Hey @smoketm, Personally, I put the flash at the bottom of the page after content. Big reason I do this is for html structure. You want your H1 tag to be at the top of the content, and that to be what search engines see first. But also remember, if you don't have a flash message, then it wont apear in the markup at all.

If you are concerned about design, and you want the flash to be at the top of the page, then I would use css to make sure it is positioned correctly.

Activity icon

Replied to Alternative To Algolia Search In Laravel

Hey @iljido I can tell you that Algolia is definitely the easiest implementation. Is there something specifically that you are having trouble with?

Activity icon

Started a new Conversation Top Rated Filter Not Working Properly.

I have a simple filter that is meant to sort companies by rating on a website. I have a controller that catches filters, and sorts in a companyfilter the companies. The same bit of code is working fine with another model.

Company Controller:

 public function index(CompanyFilters $filters)
    {
        if($filters){
            $companies = Company::filter($filters)->paginate(20);
            return view('companies.index', [
                'companies' => $companies
            ]);
        }
        $companies = Company::latest()->where('is_published', true)
            ->orderBy('is_featured', 'desc')
            ->paginate(20);

        return view('companies.index', [
            'companies' => $companies,
        ]);
    }

CompanyFilter:

<?php
namespace App\Filters;

class CompanyFilters extends Filters
{
    protected $filters = ['top-rated'];

    //Filter Query by top rated companies
    protected function popular()
    {
        $this->builder->getQuery()->orders = [];
        return $this->builder->orderBy('rating', 'desc');
    }
}
Apr
26
6 months ago
Activity icon

Replied to How To Pass Data Properly Between Components After Events

@wingly Greatly appreciate it. Thank you. I will let you know when I get this working right. (:

Activity icon

Replied to How To Pass Data Properly Between Components After Events

@joukebouke Thank you!

@wingly I can see what you are saying. Are there any good tutorials for how to implement that in this type of situation? I use this component for two different models, so I need the data to stay confined to the reviews container.

Apr
25
6 months ago
Activity icon

Started a new Conversation How To Pass Data Properly Between Components After Events

I have four different components for a reviews area on a website. One to create a new review, another to show a review, another to update reviews and a component that acts as a container for all of the rest of the components.

I am trying to update the list of reviews after a review is updated, or added, but it is not working properly yet. Below you can see the different components.

Reviews Component Container:

<template>
    <div class="_100-percent">
        <div class="horizontal-flex">
            <button
                @click="readingReviews = true, makingReview = false"
                v-if="! readingReviews"
                class="button reviews w-button">Read Reviews
            </button>
            <div v-if="! makingReview">
                <button v-if="user"
                        @click="makingReview = true, readingReviews = false"
                        class="button reviews new-review w-button">Leave a Review
                </button>
                <a href="/login" v-else class="button reviews new-review w-button">Login to Review</a>
            </div>

            <img
                @click="makingReview = false, readingReviews = false"
                v-if="readingReviews || makingReview"
                src="https://assets.website-files.com/5d6a06652927f626ea4c21d5/5db7524c65dc46b70b2a86fb_error.svg"
                alt="close-icon"
                class="close-icon">
        </div>
        <div v-if="readingReviews" class="review-container">
            <div v-if="items.length">
                <div v-for="(review, index) in items" :key="review.id">
                    <review :review="review" @updated="refresh" @deleted="remove(index)"></review>
                </div>
                <paginator :dataSet="dataSet" @changed="fetch"></paginator>
            </div>

            <div v-else>No one has left a review on this item yet.</div>

        </div>

        <div v-if="makingReview" class="review-container">
            <div v-if="isReviewed">
                <update-review :review="userReview"></update-review>
            </div>
            <div v-else>

                <new-review @created="add"></new-review>
            </div>
        </div>


    </div>
</template>

<script>
    import Review from './Review.vue';
    import NewReview from './NewReview.vue';
    import UpdateReview from "./UpdateReview";
    import collection from '../mixins/collection';

    export default {
        components: {Review, NewReview, UpdateReview},
        props: ['item'],
        mixins: [collection],

        data() {
            return {
                user: window.App.user,
                dataSet: false,
                editing: false,
                readingReviews: false,
                makingReview: false,
                isReviewed: this.item.isReviewed,
                userReview: this.item.userReview
            };
        },

        created() {
            this.fetch();
        },

        deleted() {
            this.isReviewed = false;
        },

        methods: {
            fetch(page) {
                axios.get(this.url(page)).then(this.refresh);
            },
            url(page) {
                if (!page) {
                    let query = location.search.match(/page=(\d+)/);

                    page = query ? query[1] : 1;
                }
                return location.pathname + '/reviews?page=' + page;
            },
            refresh({data}) {
                this.dataSet = data;
                this.items = data.data;
                this.makingReview = false;
                this.editing = false;

                window.scrollTo(0, 0);
            }
        }
    }
</script>

Review Item Component

<template>
    <div>
        <div class="review">
            <div class="_80-percent">
                <div v-if="editing">
                    <update-review :review="review"></update-review>
                </div>

                <div v-else>
                    <div class="author">{{user.name}}</div>
                    <star-rating :read-only="true" :star-size="30" :increment="0.5" :rating="rating"></star-rating>
                    <p>{{body}}</p>
                </div>
            </div>
            <div v-if="authorize('owns', review)" class="_20-percent">
                <div  class="edit-reply-buttons">
                    <form @submit="deleteReview" v-if="editing">
                        <button type="submit" class="icon-button delete-button w-button">Delete</button>
                        <button type="button" @click="editing = false" class="icon-button cancel w-button">Cancel</button>
                    </form>
                    <button @click="editing = true" v-else class="icon-button edit w-button">Edit</button>

                </div>
            </div>
        </div>

    </div>
</template>

<script>
    import StarRating from 'vue-star-rating';
    import UpdateReview from "./UpdateReview";
    export default {
        props: ['review'],

        components:{
            StarRating, UpdateReview
        },
        data() {
            return {
                user: this.review.user,
                editing: false,
                body: this.review.body,
                rating: this.review.rating,
                reviewId: this.review.id
            };
        },
        methods: {
            setRating: function (rating) {
                this.rating = rating;
            },
            deleteReview() {
                axios.delete("/reviews/" + this.reviewId);
                this.$emit('deleted', this.reviewId)
            },
            update: function (review) {
                this.body = review.body;
                this.rating = review.rating;
                this.editing = false;
            }
        }
    }
</script>

Update Review Component

<template>
    <div>
        <form @submit.prevent="updateReview">
            <div class="author">Update Your Review</div>
            <star-rating :star-size="30" :show-rating="false" :rating="rating"
                         @rating-selected="setRating"></star-rating>
            <textarea
                maxlength="5000"
                name="body"
                v-model="body"
                class="input-field text-area w-input"
                :v-text="body"></textarea>
            <button type="submit" class="icon-button save-changes w-button">Update your Review</button>
        </form>
    </div>
</template>

<script>
    import StarRating from 'vue-star-rating';

    export default {
        props: ['startRating', 'review'],
        data() {
            return {
                reviewId: this.review.id,
                rating: this.review.rating,
                body: this.review.body,

            };
        },
        components: {
            StarRating
        },
        methods: {
            setRating: function (rating) {
                this.rating = rating;
            },
            updateReview() {
                axios.patch('/reviews/' + this.reviewId, {
                    rating: this.rating,
                    body: this.body
                })
                    .catch(error => {
                        flash(error.response.data.message, 'danger');
                    })
                    .then(({data}) => {
                        this.$emit('updated', data);
                    flash('Your review has been updated.');
                });

            }
        }
    }
</script>

New Review Component

<template>
    <div>
        <form @submit.prevent="addReview">
            <div class="author">Add a Review</div>
            <star-rating :star-size="30"  :show-rating="false" @rating-selected="setRating"></star-rating>
            <textarea
            maxlength="5000"
            name="body"
            v-model="form.body"
            class="input-field text-area w-input"
            ></textarea>
            <button type="submit" class="icon-button save-changes w-button">Add Review</button>
        </form>
    </div>
</template>

<script>
    import StarRating from 'vue-star-rating';

    export default {
        data() {
            return {
                form: {}
            };
        },
        components: {
            StarRating
        },
        methods: {
            setRating: function (rating) {
                this.form.rating = rating;
            },
            addReview(){
                axios.post(location.pathname +  "/reviews", { body: this.form.body, rating: this.form.rating })
                    .catch(error => {
                        flash(error.response.data.message, 'danger');
                    })
                    .then(({data}) => {
                        flash('Your review has been posted.');
                        this.$emit('created', data);
                    });
            }
        }
    }
</script>
Activity icon

Replied to Ajax Request Is Reloading Page And Adding Query Strings To Uri

@snapey and @wingly Really appreciate your help. that fixed the problem. Would one of you have time to look at my reviews component and see why it is not passing events from child component to parent right? I would pay you for your time that you spend going through it with me.