Code Along Video Subscription App #19 View Components

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello so today we are going to talk about view component and this is basically a library that was developed by github with the idea of reinventing the view layer of a ruby on rails application so at the moment we've got the our views folder we've got lots of partials we've got decorators we've got the application helpers and the idea of view components is that it can actually replace it all so it brings kind of front-end direct kind of style of development into urban rails application so instead of having partials we would have new components and they can actually also replace views and the cool thing is that they are reusable and they are testable so you can easily test each component and know what you will expect to see and also there are some cool features like previewing view components so here is a real case scenario there's this uh really cool article about some guys that were building a project management application and they ended up having lots and lots of partials and partials inside partials and it really decreased the loading speed of their application and basically if you have lots of view components and your components inside your components it still performs much better than using partials so now we are going to explore using the components in a real ribbon rails application so um here i've got an application basically i've got a list of posts so each post is a partial that we've got a progress bar shell we've got uh our users logo that is visible in the navbar we've got a user's logo here if we go to my profile we have these things that can be moved into a separate component like these boolean labels that are described in our helpers application helper boolean label so now we're going to try to implement a few view components okay let's go to the guide i'm getting started and let's install the gmu component require view component engine i'm going to add this to the jump file and run bundle so first of all we will try to replace these uh labels with the view components basically instead of having the boolean label value they're going to render a view component for each of these cases so at the moment we have a boolean label with the uh value and instead we are going to create a component so rail generate component let's name the component as boolean label and it will have a param of value and what does it create it created a test file and it created a new folder in our app so here we have app components and inside the components we have a dot ib file and an html file now basically this dot rb file should describe the behavior of the html file and we can actually already try to display this view component somewhere inside our application let's start the server and let's say i'll go to the root page of our app and try to display this component that we have just generated so go into static public landing page and i will say equals render boolean label component dot new and we need to pass in some kind of value so i will say value equals abc for example and what will we get so we have the html rendered here but we don't have this value displayed anywhere well we can actually display the value by saying equals at value and here we have this abc okay now let's try to move the logic of this application helper boolean label into our boolean label component i'll take it out of there and put it here now it will be in a private method and here we have so we are going to define the batch color it will be either batch with a background success or with danger so then j is read okay and we are going to have this content tag not in our b file but in the html file so we'll have content tag span value badge color now here we have the value and the badge color and if we define the page color based on the what we have in our params here so either true or false let's see if we get anything okay we get this undefined local variable or method value why is it so because we have this contents tag span value but we don't have that value now let's try making add value and we would also make add value here and here we have this abc of course it is without a badge because it is not true and not false so i will say else and if the value is not true or not false let's say badge background secondary okay so here we have this other background if the value is not true and not false now let's say the value will be true i'll actually run the a different component with the value true and here we have the same but for the value true and it is the success now we can actually remove all this other text that we don't need anymore uh i'll remove it from here and let's see okay looks good and we'll also run the component with the value false let's see what it gives us so here we have a component with the value false okay looks good now we can actually do one more thing we can say that we don't need this at we will just have value here and here and instead we will just say attribute reader value like this and it should work just as before okay looks good so you see now we are previewing three of our view components and the actually three states of the same view component and now we can try using this two components somewhere in our application for example inside our [Music] user partial instead of this boolean label so i'm just going to render the boolean label component with a specific value now let's go to our users use a partial and here instead of rendering the boolean label they're going to render the boolean label component and the value is going to be based on a user state so user confirmed or user created by invite or user invitation accepted at okay so looks good now we've just replaced our helper with the air view component and actually we can do a lot of cool stuff with this review components for example we can preview them so the same way we can go to slash rail slash mailers to preview every component to preview an email we can also preview the view components so we can actually create some previews now we would go to our test components create a folder named preview or previews and here we would have a file named boolean label component preview dot ob and let's see what the code should be like so we'll go to previews here is an example so we will say boolean label component preview and we will render boolean label component with a value that will be true for example and we will say then true and we can render the other states of the component so we'll say then false and also then other and let's have a look at these components now i think we need to restart the rail server so that it takes effect so when we added something in our view component previews we would need to restart the server and let's click on the pen false is it fun false okay yeah i should actually change it to false now reload okay now it is red now let's go to the other states so then other here we have just this text and the ventral so looks good now we can preview our components and also we can also test them so let's go to our test and here is an example test so we can assert equal and we can expect some particular html to be rendered and compare the html rendered by the new component to the html that we want to actually have so let's test the than true and we will run the balloon label component with a value that will be true and say to html and let's run the test i will say uh rails test okay we got some error let's see okay violates unique constraint actually i will need to go to fixtures users and add some basic fixtures for users so there should be users with the emails let's say one email it will be one at superrails.com and two will be two at superiors.com okay let's try running the tests once again rails test okay so we managed to run the test and we were expecting this html but we got this html rendered now let's see i will go back and what do we expect we expect spam with a clause badge background success and inside we would have the world true let's see if it works i'll run rails test and it is nearly the same but here you see we have this extra line now let's go back to our html view of the component here we actually have this extra line so we need to remove it okay i'm running the rails test once again and you see the tests are passing so looks good and the same way we can test the other states of our component so i will also test van falls and let's actually have a look at other default options that they can have with testing so i'll go to testing and here we can assert selector or text to be present so let's try these other options i'm going to render inline the boolean label component with the value false and i will assert the presence of a class that has badge and badge or background danger and text that i expect is false okay and here i can also insert a text to be false i'm running rails test and the test process and let's assert the other option so when other test then other and the label will be let's say abc and the selector that we expect to have is badge secondary text would be abc and here it would be again abc rails test and it works so the tests are running okay and this is basically how we can test a view component again it is kind of uh isolated from the whole application logic and the just from our application when we run the uh view component we can pass anything that we want inside the params so let's go and do another example so now we did our boolean label component let's actually do something possibly more complicated for example a user avatar so here we have a user editor we also have the avatar inside the users list and also inside our posts so if a user has an editor an avatar is rendered let's create one more component i'll run the command rails generate component avatar and what does an avatar have now what does an image you usually have let's have a look at an image tag it has the source it has the size it has a class and can also have an alt so let's say avatar src is for source then alt size and yeah i guess that's it for now so let's generate the component and here it is again we've got and dot rb file and html.eib file and here we're going to have our image tag so let's say equals image tag now here we are going to have the source then we are going to have the size then they are going to have the alt and then we are going to have a clause so let's say that the clause is always going to be the same it's going to be the one that we've got here so class rounded circle and so on i'll input the clause here and let's try rendering this component uh somewhere so for example inside our user partial so i will say equals render avatar component dot new and we need to pass in some params so we'll need to have src the source would be user.image then we would have the size that would be 30 for example and we would have an alt that would be the user's name so it will be user.name and let's see if this works i'm going to refresh the page and go to our users okay rails server now go into a user page and i get this undefined local variable for src okay so we need to go and add these attribute readers so attribute reader src alt and size now let's refresh and the image gets rendered so looks good now let's go to the list of all the users and you see a new location provided cannot build uri now why is it so because some of the users do not have images so let's render the image only if it can be rendered and it can be rendered if the user has an image now the easy thing we can do is just copy this logic and put it right here but there is a better way of conditional rendering than this so view components have such a thing as a render conditional rendering so we can say render if true or if false so let's pass a variable for bandwidth to render it let's say a coma render or let's say display and they will display this image if the user has an image then we are going to display this component and now we need to pass in this param of display into our avatar component so we will also edit here display and we will say def render if we can display so if display is set to true then we can render this avatar let's see if it works okay unknown keyboard display it is because we also need to add display here display equals display now let's see if it works yeah we also need to add display here so display and undefined method display so i think we can just make like this and looks cool so in the case when a user has an avatar we render it otherwise we do not okay and let's uh have a look at some more options so we have passed our alt now each image can have an out what is a node it is a text description of an image so if we go to the image here and go to inspect uh what do we have an image has this uh username the name of the user that we've passed here and what if we don't pass an out let's imagine we don't pass an old here what will happen okay we have this missing keyword out but what if uh there are cases when we just forget to add an alt or where we don't want to have an alt where they they won't have just some kind of default text well actually in these view components it's really cool and easy to add defaults so here we can just add the default to [Music] title just default title and if you don't pass an alt then they're going to have this default title so let's see i refresh and now i will go to this image and if we do not pass an alt it gets this default title we can do the same with the image size let's imagine what if we pass the size would be not 30 but 300 so the image is bigger but if we don't pass any size what do we get we get this error so we can also add a default value for the size let's go to our size and say that by default it's going to be 30 meaning 30 in fifth and 30 in height okay so looks good and you see we added a few defaults and we don't have to type them all in inside our render of the component but when we want to override them we can do it really easily so at the moment we've just got the source it's the user image and display if it is present so looks good and now we can reuse the same component around our application so again i'll go back and add an alt it will be user dot name and size let's say it will be 50 and i will just check if it's spoken i will remove this image tag and also go to all other places around our application to our posts and here instead of this image tag i'm also going to render the partial so actually the component avatar component size will be default alt is going to be post.user.name sci is going to be pose.user.image and display if post.user.image let's see if it works i'm going to the list of our posts and it's working now here we are rendering from this component and let's also go to our navbar here we have our user image so there we can also render our component let's go to layout uh header and here we are going to have our avatar component so we don't need this logic anymore like if a user has an image then image tag and so on they're just going to render the avatar component for current user image alt current user name and display if the user has an image okay so looks good and here basically we've created and used two different view components now what if we want to actually input a big partial into a component and create a component that has a few different components inside now what if we try to move this whole user view into a separate component this can be quite an interesting challenge let's try to do this so i'll just create a new component rails generate component and we'll just name it user or user view or whatever so we'll just have the user component and we are going just to pass one attribute it's going to be the user id so use a component with one attribute user let's see what we got we have this user component and we have this dot rb file okay so what if we move all the logic from this user partial all this html into our html of the user component just like this and try to render the user component instead of our user partial i will totally remove the user partial and go to our users index and here instead of rendering users i'm going to render this collection of view components now let's see how we can do it we have this render user component with collection users so we'll say render user component let's see if it works i'm going to start the app and go to the list of users okay we have this undefined local variable user again we will have to go to our user component.ob and say attribute reader user okay and as if nothing has changed but we have totally removed our users partial and instead of rendering a user partial and a list of user partials they are just rendering their components so looks uh really interesting and you see inside this uh avatar component oh actually inside this user component we are rendering two other components the average component and the fu boolean label components so this way we have components inside of components looks cool doesn't it now let's have a look at a single user record and again we try to render the partial instead of rendering the partial we are going to render this user component let's go to our users show and here we can render instead of the partial user component at user okay let's see how we can do it so i would maybe say user equals at user undefined method user component maybe i should say dot nu and it seems to be working now will it work without this user let's see okay so now we are rendering our user and actually what if we totally remove this show view and just inside our user's controller we will say that we want to render this component instead of rendering this view template so i will try to go to our users controller and in the show view i will say that i want to run the user component new for this user let's see if there is any change here now i will try to add some kind of random text in the show view so nothing is changing it is because we are not using this show html view so i can totally remove it and what do we have inside our users we have only an index page and we have this user component and uh i think it's uh really interesting that we don't have a user show we don't have a user partial but we are using the components instead of them and now we can actually also try adding a few previews for our images and for our users so if we go to rails view components and here we have a preview only for our boolean label component let's also create a few previews for our avatar component and for our user component so what would it look like let's see we need this view component preview and here we have avatar component preview here we run the avatar component and we are going to have a few options now let's say we will render an avatar component in a few different sizes uh how could we do this well what if we say default and it will be an empty method and here we are going to create a new folder named i guess avatar component preview and here we will have a file named default dot html dot erb okay and here let's try to input some kind of random text so i will refresh and see if we have access to this view i will restart the server and you see they actually have access to this html template name default and inside we have this random text so here we can actually render a collection of avatar components let's try to do this so we will have something like a few different sizes we would say a size like 10 30 50 100 dot each do size and and we are going to render a few different components so we will say render avatar component and what are we going to pass so we are going to pass the s rc then we are going to pass the size and we can potentially pass something else so what do we have in our avatar component let's see if we go to ever the component so by default we also have this display now by default let's say it will be false so we cannot display if we have no src also okay so display will be true and we'll have to put an image source now how can we do this what if we try just adding a random image from the internet let's try doing that what if we try this image i'll try to copy the image link and place it here let's see if it gets rendered so the size is going to be the size and now i will refresh okay encountered a syntax error let's see yeah i forgot to close the braces we'll get undefined forever the component so we'll say edit the component.new and it works so here we're rendering a few different images and you see again this is kind of detached from your rails application these components can potentially live outside of your current application and you can just uh preview them and add them with any kind of styling and any kind of params that your application is using so this way you can actually have your own application style guide and preview all the components and the the styling for them and again you see it's really versatile so for example for our boolean label component we had a few different previews like uh when true and false than other and for our avatar we have a collection of different sizes and we can again use an applique an image that is not attached to something particular in your application but like an image in the net so looks good okay i think it's enough [Music] for now so we've actually done quite a lot we've uh created a few different components like one component that takes the logic out of our helper and is moved into a component the boolean label component another one is for image tag with our avatars another one is for our users where they totally remove the the show action and the user's partial and move them to a view component and instead in a controller we are rendering a view component and in our users index we are rendering a collection of user components so i think uh a great job in getting to know the few components a little bit on the surface of course there's still always a lot to learn and to feel in real practice but it's all up to you now so thanks for being with me and have fun coding
Info
Channel: SupeRails
Views: 242
Rating: undefined out of 5
Keywords: ruby, rails, ruby on rails, tutorial, programming
Id: qzqh4zSZFCA
Channel Id: undefined
Length: 34min 8sec (2048 seconds)
Published: Fri Oct 01 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.