Horses On Rails - Part 2 - Simple Search

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
today we're gonna make one more use of our partial in that we're currently using the partial on the show page for a horse as well as on the show page for a breed to show all of the horses that belong to that breed I'd now like to add a the ability to do a little bit of search and just like a very simple search to search for horses by partial name and then sort of display the collection of horses that match that and for that we need to form and we're gonna need a controller action to take the data from that form pass it over to active record and actually make the query and so let's look at where we want to put that action we could make a separate controller like a search controller and often that is sort of the way we might go about it I think I'm going to perhaps piggyback on to the horses controller and add it in here yeah let's see if that proves to be a good idea or not I'll do a quick little experiment so I had a search results here and what that means is that I'm also going to need a search results of view in the horses folder right here so I'm gonna go make that file search results dot HTML BRB search results go here so that's just temporary text that I'm just putting into that view because I want to see if I can expose this controller action and this view by way of a route I'm gonna have this route respond to or I'm gonna have this action respond to a get request and so what I would like is maybe something like horses slash search results something along those lines and with the option of like passing along a parameter what we're searching for and that's going to come from our form so the forms gonna post with a get and it'll go here the reason I'm not using a an actual post from the form is just because sort of convention around search results on the Internet is that search results should be shareable you'd like to be able to have a link that you could like send to someone else or maybe even save for yourself if you submit with a post you can't bookmark that if you submit with a get request and the search result query is in the URL you can bookmark that so it's just sort of sticking with internet conventions I've got to go into the the routing file here and here's the part that I always forget so I want to add see we're already building up everything with resources here and we're asking just for a show route I should be able to request another collection route going off of memory here so this could be completely wrong I get requests to search results goes to oh yeah let's let's see if just let's see let's see if I go to rails info I'm gonna get to see the route there and that looks like what I want I get requests to slash horses slash search results is going to call the horses search results controller action so should be able dish to try that horses search results and search results code here so I didn't really explain what I was doing here when you add a block a do end block to resources you can go beyond the seven restful routes right so we've already restricted our seven restaurants down to one but now we want to add more there's two types of routes you can add to a resource collection routes or member routes collection routes have to do with the entire collection so like the index page is a collection route and a member of has to do with one member in the collection and it always has the ID along with it and so if I defined like a new member here that route would have like the ID tag or sorry the ID placeholder in the URL as part of its definition so I'm not dealing with a particular member here that's why I defined this as a collection route that I'm adding to the horses resources okay that that's good that worked I remembered the brain is working let's commit this added a a search results collection I mean I could have also just built this road up completely manually I could have said like I get requests to and then just sort of define the path and where it goes to but the idea of like collection and member routes is paired with resources then the next question is is like where do I want the forum to go with the search form and I'm gonna just default to the idea that I want this to be present on all pages and so I'm going to put that in my application layout so I don't need another view in which to put the form I'm not gonna send my users off to a special search page I'm gonna have a form that's present on all pages so I'm gonna go to the application here and I will let's say I put it in the this top section now our initial gut feel when were in an HTML document is just to start you know typing HTML but sometimes in rails that's not the right thing to do sometimes we use helpers to build HTML for us like the link to helper and so we have similar helpers for building forms and those are even is it more even more important to use those helpers and we'll see why in a moment so here's action view form helpers on the guides so I click through to the action view form helpers guide and lo and behold the very first example is a generic search form and so I can just copy and paste that code into mine and make a few modifications the URL is going to be here and see the name of that route that I just created rails info as a name of search results horses path a long name that's where I want that to be the method is a get this is going to generate for me a label tag that says search for that label tag is going to be paired with a text field tag with a parameter or a name of Q I'm really like Q so much maybe this is its Q for query so let's just write it out that's what the user is doing their query about search and then a submit tag that has the word search in it and so if I go back to my application I see a little form not styled yet in the the boma styling way maybe let's see if we can quickly add some styles to that what do you want me to do for styling oh it's more than I want to do right now that's a lot of it seems like a lot of work I'm gonna I'm gonna leave this dialect for now let's just stick to the form if I look at the view source here let's see what the generated output is the other reason I was sort of hesitant there is that the default output is not going to match the structure of what boma is gonna want to file so here is the form that's being generated you can see it's got an action that's going to the path that I asked it to go to method is is a get request and it's got there's my label there's my input etc etc so I should be able to submit this content and have the content appear in the params hash same place where we go to get IDs and I should be able to query parameter position query to get that data and so that data is going to be sent by way of a get request here and then I should be able to get the query by going to the params a position query and I'm just saving it to an instance variable so that I can display that in the view as well so something like your search for query returned this many results and so I could say something like that your search for query returned and results where we'll fill in the blank for n in a moment that looks good let's see if it works testing and it doesn't and that's because it's because things with rails have changed a little bit I need to say note false let me just see often rails is a bit of a moving target like all things on the web local true let me see if that is the thing that I yeah the reason I had to put that local true in there is that by default rails tries to do everything with Ajax so what it was doing is it was sending that data back to my server with JavaScript but that wasn't then gonna refresh my page because it wasn't going to cause an actual page reload and so in some cases that might be helpful right you could then reach sort of repopulate the page with JavaScript but we're not there yet in the course so I'm just set local to true so that the the the the form wasn't hijacked by JavaScript and it was just sent through like an ordinary form so you can see that was that was solved with this extra parameter right here local true when that got submitted you can see up here there's the query I here query equals testing and if it was like a multi-word query multiple birds are here multiple words are here appears up there they're separated by instead of spaces by pluses which is the convention for URLs because the space isn't the valid character in URLs so my deed is getting through that's good and now I need to use that data in a query to actually query the horses table and so I can say like horse dot air and all initially do a bit of a naive query and then I'll improve my query I guess I need to save this to horses and then I'll say like wire name this query this is naive in that it's gonna do a full word match right so I'm only if I you know search for the word Kyle it'll only return you know horses with that exact name not not a partial match and so now within my search results I could say something like instead of an I could use - this this Lorelei's and the two things that I want to pluralize are horses stock size and the word so if it returns one result or if it returns multiple results it'll-it'll properly PluralEyes based on the size of the return data and then just like I did on other pages I can use my partial to render out these these horses and so I need a div a class of columns into which I do my rendering and I'm going to just cheat and go to the reads show page and pull in this information from there so all those three lines from the breeze show page and put them here and then I notice on that breed Sophia I also need the is multi-line the collection now is at horses so that will go and it will render a partial which partial well it's gonna go into the folder that I'm in so I don't need to pass it anymore it's a motor II in that folder it'll render that once for every horse in the collection and it'll add links so that people can follow from the search results into an individual horses page I'm gonna go get a name of a horse that actually exists Olaf Olaf the horse okay laughs your search for Olaf returned one result great makes me happy that worked but again a bit of a naive search right you probably the ability to search for sort of partial matches given the data I'm working with here it's not super it's like single word things so like even partial matches doesn't match the data that I'm working with necessarily but we could search for things like single letters and see like all the horses that contain the letter A or the letter T or something like that so that's that's how we'll expand our search but all I'll save I'll save what I've done so far here so to make this less naive I don't just want a one-to-one match between the name and the query I have to hop down to a little bit of sequel here because I want what sequel uses when we want to do a partial match which is like a like query and so I want to find a horse where the name is like something and I put the question mark in there because I'm I'm dealing with user data and if I was to take just straight-up user data and echo it or concatenate it into a string I'd be opening up myself to sequel injections so active record has protections in place for sequel objections in most instances but once you start like building snippets of sequel by building strings based on user input and then like filtering those off down into active record that's like danger territory right that's pure sequel injection ready to go so let's not do that and let's compose a string that will then get put into that place this is similar to what we did when we worked with like PDO in web dev 2 and we would leave placeholders in our queries and we would bind those parameters and so this question mark I can have as many question marks as I want in the the first parameter here and then the following parameters are what should be put into each of those question marks I only have one so in here it's the query that I want but it's more than just the query that I want what are the wild cards in sequel who remembers you got it and I want them on either side so build a string with the query in between two % saying like wild card on the right and wild card on the left and then drop that in or have active record drop that in as that parameter that should now allow me to do a search which will result in partial matches with my query and so a 40 results all the different forces that have an A in their name I can't really see if there's any similarities that maybe go beyond that like ER do you have an ER in your name there you are you're Peter Pan or you're a traveler or you're a challenger or pepper or tiger or trigger so it looks like things are working I'm making use of the partial that I had build up last class the form still not looking that the rate because I'm not going to style it but at least it's functionally doing what we want the form is sending a get request which is putting the query into a get parameter in the URL I'm able to tease that back out of the URL by way of the parameters end up and then I can put that into a wild card depending on in my case I wanted wild cards on either side of my query and then use that in a parameterised like query with a where clause and if we looked at the server we'd see the actual sequel that would have been generated and that is right here select horses dot star from horses where name like and then in quotes percent a percent or percent whatever I've queried percent and that is a very quick implementation of a simple search in the project you can take it a step further and search based on some category and so but that would look like in the terms of this project is maybe you would want to limit your search to a particular breed and so for that we would add like a drop-down selector in this form to allow you to first either pick all breeds or one of the breeds in the system and then that would also be submitted to your action and you could make a more complicated where Clause you could do an include to bring in the breeds table and then you could chain on another where Clause to ensure that the breed that the user had selected and their query is going to match the breeds that you're querying when performing your active record query so that I'll leave up to you to figure out if you want to do that aspect of the sort of the more advanced query in I will give you a hint that if you go to the rails overview notes it does explain how to sort of work with the form helpers to have the form helpers automatically make the drop-down list for you so like a drop-down list in a form is like a select tag with a number of option tags well you can have rails build that for you using a combination of the Select tag helper and the options for select helper you just need to give options for select an array and in this case that would just be all an array of all of the breeds that we have in the system we have to add one other element to that array which should be just like the word all because you would also want users to be able to search across all and then here in the search results you would maybe have an if-else statement like if it's all and just do this query if it's something other than all then do a more complex query that takes the breed into consideration and so I will submit that improve my search to include and I think all queries are default that default to being case insensitive so yeah and so that I believe is a function of the database that we're using I believe if we were using Postgres it might be a case sensitive query and then we would have to go to change our like to and I like and then I like is the case insensitive version of query in in Postgres but in sequel light of the like query is just case insensitive by default any questions or comments on what I have done today to implement a search if we recall but the route I took was I started with routes I added a new route to my horses resource I made a action for it and an associated view I decided to put my form in a place where it would appear on every page and I used the form with helper along with a few of the tag helpers to build up my form and the one thing that I had to do that went beyond what was in the rails guides was to set local to true here so that we didn't have the form being submitted sort of behind the scenes with JavaScript and you could see that if you if you leave this off let me go back over back over here let's go back to the home page if I go to the network tab we should be able to see the the Ajax requests sort of happening in the back hand so you can see there there's the Ajax request and [Music] the response but like that's that's not what we want in this case we didn't want things to go on behind the scenes because then we would have had to handle them differently from behind the scenes and there's different ways that rails can use JavaScript to inject new data back into the page but we're we're not going to go there today so I will put this back to to where it was so any any questions about any of those steps or or anything that I've covered today it would be something you do yourself and so just like string manipulation techniques yeah yeah but at the end of the day you're gonna have to whatever you break up you're gonna have to filter off to active record anyways and I see you could definitely break that up and there are a few search gems out there that like can make sort of more advanced searching easier let's see if I can find a few of which one of these is the one that I want we have searched it's been a while since I've used any of these I found the last time that I tried to use a search jamón rails that it was actually more difficult just learning it and then building it myself you could do it either way active record is smart enough so you could like after you've composed something like this in an if-else statement you could then like go and add more yeah that's right that's right so yeah you could build it up piecewise so you could do this initial where and then you could have your if-else of whether this is a category based search or not and you can add to the active record query by chaining on more things yeah you're chaining ends and if you need to chain ORS those are done a little differently we just got ORS in like when the last five X releases and but there's like a dot or that you pass a whole separate active record relation to so you can do both ands and ORS now yeah this is probably a lot of manual work yeah so there's still be some manual work associated with that kind of search in rails but maybe not as much there you go any other questions or comments on adding a simple search like this to a rails application yes yeah so rails has a whole JavaScript sort of reactive system built into it already part of that is what's called turbo links and another part of that is you can actually just create JavaScript views and what they can do is they can target particular portions of your page and render partials into those portions of your page and so you could have this do like you could go do a search here and that would go on the back end and then JavaScript could come in find a particular div in the page and yeah inject the partial over and over and over for each of the search results I don't teach that style of JavaScript anymore in this course but I do have a video on it and so I'll send that out in learn and you could sort of see how that's done because it's actually really really cool and for myself when I sometimes when I need just a little bit of reactivity in my app I'm not gonna bother going to something like view and I'll just use rails is sort of built in reactivity like that any other questions before we're done or before we move to marking okay I will stop the video then
Info
Channel: Kyle Geske
Views: 370
Rating: undefined out of 5
Keywords: Ruby, Rails, Ruby on Rails, RubyOnRails
Id: 3-0FxdYbBOc
Channel Id: undefined
Length: 32min 6sec (1926 seconds)
Published: Fri Oct 25 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.