Horses on Rails 2020 - Part 2

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
and so there's two things that I wanted to add what we had done today one of them was just to make the partial that we implemented a little bit more flexible and so right now we have the partial which is like a card and it's being displayed on the horse show page multiple times and then on the individual horse pages it's being shown one time for that horse but I just wanted to show how we can sort of customize that partial a little bit one thing that's a bit awkward about the individual horse show page is that the name of the horse is still a link and it's a link to the page that we're already on right so it's not the end of the world right if we need that link in the partial here so that when we can click on the name of the horse we get to its own page but once we actually get to the page here they don't need it so much anymore and so it would be nice to have like a way of like passing in a flag to this partial so that sometimes we show the link and sometimes we don't and so I'm gonna open up that partial if we remember it's in the app views horse's folder there it is right here and it's this right here this link to the horse that either should be the link or maybe it should in some cases just be the horse's name so I'm going to it's inside of a paragraph tag I'm gonna separate that paragraph tag out so that start and end of the tags going to separate lines and I'm just gonna invent a flag one that doesn't actually exist yet so what I would like is I'd like to be able to have a flag that says if show link then it'll show the link otherwise it'll just echo out the horses horses name so this is this is my my little bit of logic and so on the horse show page it will just display the horse name on the breed page where we're showing a collection of horses it'll show the links now that show link variable doesn't exist anywhere yet and just for testing purposes I'm going to make it exist up at the top here and so above line 1 I'm just hit enter a few times I'm just gonna make a little block of ERD where I can bring that thing into existence and set it to either true or false we're eventually just gonna remove that I just want to test out my logic I want to test to see if this if-else statement properly works so with show links set to true when I go to this page it should still be the Zak sandwiches just still show that link which is links to itself but if I said show link to false the link goes away and so the links gone everywhere even if I go into this multiple pages you know more links put it back to true buncha links so the logic is there I now just need some way of passing in that flag to the partial when we render it and we're rendering it in two locations so I'm gonna remove these three lines and then we're rendering it in two locations we've got it happening once in the horses show and once in the breeds show in the horses show we're rendering it with just a render horse statement and in the breeds show we are rendering it again with a render statement but this time we're passing in a collection so that renders over and over and over these are sort of the short forms of a more explicit way of calling render and if we want to pass in extra flags we have to go to that more explicit way of calling the render command and so I'm going to start with the app views horses version and I'm gonna make it the more explicit version I'm gonna say render partial horse and then I'm gonna go to the next line i'ma say using the object horse and so that is the same thing the other one was just a short form way of doing it that worked because of naming conventions because my object was of type horse and because I called the partial horse and and and all that jazz I could get away with the short form so if I if I save this nothing should change I should still be able to go back here oh oh yeah I still have that that link so I need to make that link come into existence the show link flag and so how I do that is I can add a third parameter - or sorry a third argument to render and it is locals and locals is just going to be a hash and the key value pairs of this hash become variables and data in the partial so if I in this hash create a key called show link and I set it to true well then inside of the partial I'm gonna end up with a variable called show link that has a value of true and I can pass in other things as well I could have you know even more like some some other flag that was false or something like that and then that would both of those would then be come with variables inside of the partial I only need one in this case so we now have render partial horse the object is horse and the locals we have a single local show link true if I go back over here it works this is really the page though where we don't want to show the link and so I can go back over here and I can turn show link the false and then no more link so we've customized it on this page that's great a few warnings in the other section there was a few students that wanted to remember the shortened form of this and so they they left it in inside of a HTML comment it looks like it's commented out but if I go to this page again an error and the reason is is that the HTML comments don't actually prevent the ER B from executing you can have ER B that generates stuff that will generate inside of comet blocks so just because you've commented it out with HTML doesn't mean that you've actually commented it out in terms of Ruby code to do that I believe we need to add a Ruby comment as well that doesn't work either encountered a syntax error like that does that work yeah so I replaced the equals with a hash mark so that's just sort of a general thing to know about er B is that if you try to comment out some er B with HTML comments it actually doesn't work you need sort of a pairing right if you don't have the HTML comments and you comment it out like this yeah it won't execute anymore but now it'll oneit I was figuring it would show up in the page did it show up anywhere a didn't that's cool okay so that I get maybe that's a new thing cuz it used to be that it would then show up in the page and you had to sort of pair the HTML comment with the eeob comment but it looks like that's the best way to do it so if you want to keep that in there you can just to remind yourself of that shortened form I'm gonna remove it myself and then we're gonna go over to the other location where the partials being rendered again it's being rendered in a short form this time with a collection it's we need to type in what the long form is for a collection partial and that is a little bit like this we say partial and I'm gonna fill in that string in a second we're stating that this is for a collection and there's the collection we're still defining some locals and we're saying that show link in the case of the multiple horses page should be true and for the partial we have to do sort of like a pseudo passing to the partial it's not like a real path because we're not putting in like the entire file name but we're gonna specify that this is a partial in the horse's folder called horse and so we're not really passing because we're not including the underscore or the HTML DRB but we're just hinting to rails that the partial is located in the or is view folder and it's a horse partial so we look at those two the only real difference is this one has an object and we're passing it a single object it'll render it once and our locals is set to show link false there and then here it's a collection and we're passing in a collection and locals is set to true and so if we go back over to our page this works well no link this worked well there is a link on each one of them so that's exactly what we wanted to see so that can be done to make these kind of partials a little bit more flexible you can get carried away with it though if you find yourself adding way too many locals way too many flags like the whole point of a partial is that you're taking some kind of duplicated data and removing repetition in your code if you have tons and tons of locals that you're passing in that are changing the behavior then it's probably not actually any real replication you're maybe just making things more complicated than they need to be the other thing I'm going to quickly show you it's just one of the things that I often do with rails to sort of see how things operate is I look at rails projects where some scaffolding is being done and so if I open up the the demo blog that I showed you earlier on in this course where we scaffold up a blog if I go to the app views blog posts folder we can see that there are partials there as well there's one partial in there which is a json j builder partial this is for when you are using rails to create a json api and so this is a partial that sort of explains how a object should be generated to produce json so it sometimes you might want to leave off some of the properties sometimes you want to modify them slightly so this particular partial is called a J builder and it's how we build rails api's the other one that we can find in that folder if you remember the blog the blog was set up in such a way that there was a page where you could create a new blog post and a page where you can edit a blog post and if we look at the new and we look at the edit neither of them actually contains a forum they both just render a forum passing in a particular blog post and if we go to the forum partial we can see that's where the forum actually lives because it's the same forum like it has all the same elements if we add to this forum well now we only need to add in one place we don't need to change the forum on both the edit and the new page so just another example of how partials can be used in a rails application I'm going to show you one other use of that because we're about to do something new with our app which is to add search capabilities sort of a simple search to our app before I do that any questions about the partial that we just modified okay so I'm just gonna commit this change here data the partial - a link so what I want is I want a the capability of doing a search hunt like a little form it's gonna have a single text input and a single submit button and when I submit that I want to use active record to search for a horse by name initially I'll make the search a little bit naive in that it'll only search by like full name and then we'll make it more flexible that where we can search for like a partial name and it'll find partial matches so we can search potentially just with the letter e and find all horses that have the letter e in their name or something along those lines and so for that I'm going to make use of another another partial what I could do is I could go into I want this search to appear on every page so I could go in here to the application layout and I could put the form right here but then I'm sort of starting to over complexify the application layout I might it might be better to keep this form in its own little isolated area so sometimes even if you're not gonna use it in multiple places it'll be good just sort of abstract it out and so I'm gonna put a render statement in here just gonna say render partial shared slash search or maybe it's it's related to the horse so it'll be like forces /search and then I'm going to go into my horses folder and I'm gonna make a new file and it's gonna be underscore search dot HTML da d RB I was initially thinking that I would make a whole new folder in the views folder called shared and just put it in there but this is really related to horses so I can put it in there so that's I've got that in here this is my layout file it's got render partial horses slash search and just to test that it's working in this search partial I can just put in in groups and what we should see is that when we go to view any page in our application right below the header but above where the view gets rendered we should see that paragraph that it says it works there it is on the the root page there it is on the breed show page and there it is on the individual show page so that works now I actually want it to be a search form so I'll first make it a search form and then I will add some Volman styling to make it look a little bit nicer when you think about how we build links in rails we use a helper we use like link to and it builds the link for us the same thing is going to go for searching we're going to use a helper to build the form for us and I'm gonna copy and paste some code from guides dog Ruby on Rails org so if you're coding along you might also want to go to guide star Ruby on Rails org so that you don't have to type out the same code and there is a whole guy just on actionview form helpers and if I scroll down example 1.1 is a generic search form which is exactly what we need and so that I'm going to copy I'm gonna copy the five lines of code that are in section 1.1 so if we look at this here we have a few things that says form with and then it says URL slash search method get' what that means is when this form gets submitted it's gonna make a get request to slash search I'm gonna change that in a moment we're gonna make our own custom route for where our search goes to but that's fine for now and then inside it here it's creating a label tag that says search for a text field tag that's gonna generate some input and input tag and a submit tag so if I save this we know view source and see what this actually generates so there's what it looks like again not styled yet here's what it looks like in the markup now we can actually put those sort of like on the same page here so the form width and the end generate the initial form and the close of the form so we don't have to close the form our cell if it gets auto closed at the end the form with generates the start of the form you can see there it's the action is set to search I could change that here the method is set to get that's happening over here you can see here this is something called data remote true this is cuz rails tries to do everything in an ajax ii manner it tries to not do full page refreshes so when you submit a form the default behavior is to send that form off using javascript so that it doesn't actually reload the page in our case we don't want that behavior i don't want to get into some extra complexity here and so I'm gonna add a local true to I search form here and so that when I reload the page it becomes just a regular form action it doesn't say that remote data in there anymore this label tag right here is what generated this label this text field tag right here is what generated this input of type text and you can see the letter Q is what set its name and it's ID and then lastly the simatech generated input of type submit' and a value of search so I'm going to make a few changes I'm gonna remove the the label tag I don't need that I'm gonna change this to search term so that is what that's good when I submit my search it's going to be known as the search so whatever the user searches for will be known as the search term everything else can remain the same so again if I reload this and we look at that form in markup land there it is you can see things are the input is now labeled search term if I go to the page and I reload it I just go to the room I'm also just temporarily gonna set the URL to the root path because what I want to do is I want to see what actually happens when I search this form where does this data go and so I'm just gonna put latch in there and if I click search we can see that we are still at the root and we've got question mark search term equals flat so the search went into the URL and that's because the method was get if I set the method to post that wouldn't have affected the URL and it would have gone into rails as params hash but when you're building out searches it's sometimes handy someone might wanna you know send you know the URL of an existing search or save a URL so it's it's typically best practice to make searches get requests and not post us so that they can be linkable and shareable and all that kind of webby stuff so that's what happens to our search term anything we put in here ends up in the URL and just a regular get parameter key value pair behind the scenes that also in in terms of rails goes into that special params hash and we've used that params hash when we were pulling out like IDs out of URLs we can now also use the params hash to pull the search term out of the URL and so now I need a few other things I need I don't want to send this to the root path I want an actual action that I can send this to and a view associated with that action and a route associated with that action so I need three things so I'll just commit these added a search form yeah a full Valeo and then I want to open up the routes and horses controller I'm going to need to create a new view in a moment as well so in the horses controller I'm going to create a search action there's nothing special about that name I've just named it search and when I set up the route I'm probably gonna make it just yet live it like slash search and it's going to have based on the form remembering that the search term is gonna come along for the ride search firm equals user search so this is just a comment that's helping me remember how this is being implemented and it's within here where I'm actually gonna perform the search this search term ends up in the params hash so I can search for horses using the horse model where and initially I'm gonna do a bit of a naive search I'm just gonna say name : params search term and this is naive in that when you do a where Clause like this it's an exact match so if I search for exactly the name of a horse and there is an exact match to a horse in the database with that name it'll it'll find that horse but if I search for a partial name so if I have a horse named misty but I search for mist it's not going to find anything right now it'll only find the the full exact match I still need though to actually define this route in the routing file and I need a page on which to display these search results and I already have a partial that I can use to display them so that's nice so I can define the route I can define it at least initially just manually I can say a get request to slash search should go to the horse's search action and within the views this should be known as the search path this is this search now that I have that route I can use it within my form because right now the form is just going to the route and we just did that for testing purposes I actually want the form to send its data to this search path so that the data gets sent to that action that we just wrote so in the form a chain CH this URL where the forms gonna send its data the search path so we're just sort of wiring things up but now the form exists on every page when the form gets submitted it will send by way of a get request to the search path at slash search that's gonna then trigger our route which will then invoke the search action in the horse's controller at which point I can go and pull the users search term out of the params hash and search for my horses and so the very last thing to do is to make a view to display that data and so in my views I can make a new file and I can call it search on HTML ERP so a better name for our partial might have been like search form because now I have like search that HTML the DRB which is actually the search results and I have a search we can fix that up maybe in a moment rename some things but nonetheless in here I just need to have a div with a class call UM's and then I can just render out my partial in fact I can just copy what I did inside of the August writer I was importing we're a long render partial forces / force for the collection horses and then I do want links so locals show thanks and then I can close up that div the div needs to be there just because we're rendering those cards as columns just like we did on that show page for the breeds and want the same for our search results everything should now be wired up correctly we display this form on every page when the form is submitted the data gets sent by way of a get request to the search path that triggers this route which in turn triggers this action which in turn does the actual searching making this at horses variable accessible to the Associated view the view of the same name which is the search let's see if I made any mistakes first I want to know a name of a horse that actually exists like brandy brandy Oh blows up undefined local method so doesn't like my show link oh it's because it's show links oh yeah show link that's it it's just a typo there my locals is show link singular there's brandy if I search though for bra doesn't find anything and so I need a little bit more flexibility with my search it works if I know the full name of a horse but that's not like if you already knew the full name of the horse you probably wouldn't be searching before I go and make some improvements to the search does anyone need to see any of these pages that are up here the partial or the routes or the controller or the search result page all right let's make a little bit of improvements it is bothering me this naming so I'm just gonna change the name of my search partial just a search form and then in the application layout I need to change that as well looks like it's still working miss G yeah they're suppose to let's make the improvements then to the actual search when we're working with sequel we can do non exact matches what's the wild-card character in sequel it's the percent yeah and so in rails when we have a perfect match we just do like the key and the value if we have something that needs to be a little bit more customized in the where command here we can write like the little snippet of sequel that we'd want to be part of the sequel where clause and so that little snippet of sequel I'm gonna put it inside a double quotes and it's gonna say like where name and when you're doing a a non exact match in sequel it's the like instead of the equal sign that you use so where the name is like and then in single quotes I'm going to put in a percentage and I'm gonna interpolate in my search term and then I'm gonna put a percentage at the end of it so that I'll take whatever the user searched for it'll glue wildcards on either side of it so that when we search it yeah it'll have those wildcards on both sides so it'll it'll perform a sort of a full partial match but there is there is some problems here Danger Danger Danger Danger all marking there this is a there's a major problem so all this will this will solve the problem of the overly specific search but I have put a security hole into my application so we're gonna have to fix that in a moment as well is it fine sequel injection nobody nobody knows that what sequel injection attacks so if I search for misty it still works if I search for mist it finds misty if I search for the letter I it should find all of the animals that have the letter I on it it looks like I forgot in the search page to specify is multi line that's in the search but HTML DRB beside columns so if I search for the letter e for example there's every horse with the letter e in its name there are a few genes there's only one chain before I fix up the the problem that has to do with the sequel injection we could also in here do something like found oops I made that just a little message right at the top found I'm using the PluralEyes helper so it'll take the size of the result set that's found and it'll either say found one result or all I don't even need results here it'll say found one result or found two results found three results for the search and then I'm also outputting the search terms of the user for and that on the page now when I search for the letter e it says found 33 results for the search maybe it says for the search they are found 10 results for the search term here save this to get I could say implemented a simple search currently there's a sequel injection issue when you're operating with rails and you do what we were doing before like when we just said like horse we're name and search term blah blah blah there's no danger of sequel injection here because rails is gonna generate what's called a parameterised sequel statement and those are guarded by sequel from sequel injections but when we just go and we build a little snippet of sequel and we take some data from the scary internet and we just paste it right into our sequel string that is like a prime target for sequel injection and so we need to fix that and there is a simple fix though and what that simple fix is is I can put a question mark in there I can make it a parameterised search so I guess a horse where named like question mark we can have as many question marks as we want in a statement and then after that for each question mark we have to put a comma and then another argument for what should go into that question mark and in our case it's a string with the parameter mu interpolated inside of two percentage signs so effectively I'm gonna be generating the same sequel what I'm doing now the generation by way of a parameterised search not by way of just building up a string and that will protect me from the sequel injection attacks I can take my changer message away now and so if I go back my my coach still worked the same and it does we're almost done for the day the very last thing that I would like to do is just add a little bit of styling balm of styling to this but I won't make you watch me do that I'll just record that after class and I'll add it to this video so I'll just pause right here and I will unpause now to continue the styling so this is the form that we want to style and we want to style it using Bulma and so I'll go to the balm of documentation go to the form section over here and just to the general section we can see how the balm was styled a number of things and I know specifically there is an example of a search form down below where the input and the button are stacked side by side here's what we want and so I'm gonna copy and paste an entire snippet of code and drop it down below here and so this is code that's going to go inside of a form itself and it begins by like here's the input I'm gonna remove that and I'm gonna replace it with my text field tag here is the search button so I'm going to remove that and replace it with my submit tag and I'm going to put it back into the form itself so remove the input and I will take mine put it in there I'll remove the cement and I'll drop it inside there and now I will take this end of the form and I will put it at the end here now that does some of the work the things that I removed though the input for example has a class of input on it and the button has a class of button is info so I need to get those classes back on to my input and my button but notice that my input and my button are generated with helpers so I need to figure out how to get those helpers to generate classes for me and so I'm gonna go to the rails Docs for those things I'm going to go to the rails API I'm going to look up text field tag to begin with text field tag name value options okay and if we look deeper here we can see some examples of when we're using name field tag we want to have it create a class or if we want to have it create a placeholder we and we don't have a value that we want to assign to this thing initially we can see leave the value as nil and so I can go to mine here's the name I can give the value of nil then I can specify class and according to the boma docs this will be a class of input that's from right here and then I'm also going to give it a placeholder just a little bit of placeholder text that'll be in in light gray so I'll say place holder search this is my name and then for the submit tag I'm going to go back to the API I'll search submit tag do a quick look there and it looks like it's value and then options directly afterwards again if we look down below here you can see an example of assigning a class submit a name and then we just say class and what we want it to equal according to as the class should be equal to button is info so I'll copy that in here I'll say class I'll paste on it so we've now properly styled this form according to Bulma we've wrapped it in a field that has add-ons that's going to be the has add-ons gives the ability for them to stack side by side nicely if we go back to the page and we reload it that looks nice very nice-looking it's a little too close though to what follows below it and so same thing goes for it you know after we search I'd like maybe the search results to be a little further down as we navigate around the site you can see there could be a little bit of margin maybe between there and there so I'm also going to give my form some a class so that I can target it for styling so I'm going to look at form with and maybe see how we can add a little bit of a class to that as well form with model scope URL format and options is everything else okay so let's try so let's see if I can just put in a class of search form so it's just a class that I am making the name up of myself so if I go back over here my view source we should see there is my form it does have a class you can see right here of search form on it which means I can apply some styling to it just using the styling that we had set up last time in the app assets folder and the style sheets subfolder there we had set up our own little style start s CSS file any of the scss files we put in the style sheet folder get automatically loaded so I can go in here and I could say a form that a class of search form should have a margin bottom of two round and we go back over here and there we go that looks nice we can navigate around between our various aspects of our website we can perform a search to find it maybe this needs to get pushed down a little bit that right there is a search results page that's this right here in between the columns and here so I could give this a class of search results and I could say if dot search results margin top one room yeah that looks a little bit better and if I search for the letter e we'll get a whole bunch of them back and I can go back to the main page we've now fully implemented our search it's styled you can see the the fact that it's got the placeholder text in place it says search horses by name that's a little dim for my liking but we'll leave that for now and so thank you very much for sticking through to the end here and watching me implement a search in our forces on Rails example app see you next time
Info
Channel: Kyle Geske
Views: 405
Rating: undefined out of 5
Keywords: Ruby, Rails, Ruby on Rails, Rails 6, Search Form, Bulma, Bulma.io
Id: 8OQTNJ5DG0g
Channel Id: undefined
Length: 47min 34sec (2854 seconds)
Published: Fri Feb 14 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.