Realtime Rails with Hotwire & ActionMailbox | Part 1

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] hey guys this episode we're going to be building real-time application with action mailbox and hot wire which is um the example that i talked about in my railsconf 2021 talk so we're going to build a customer support application with hotwire so we can have conversations and messages show up in real time and we're going to be using action mailbox to receive inbound emails for those conversations so when you write a response to someone it will send out an email and they'll be able to reply by email to continue the conversation that will get processed by rails and inserted into the correct conversation and we'll go talk about email headers for threading those conversations in the right email thread in your email client like hey gmail outlook whatever you're using it should thread all of those together because we're going to be referencing those with our email headers now there's a lot to talk about so let's start off by building our rails applications basics which is our models so i've got a brand new rail 6.1 app installed and there's nothing to this just the basic application so i just ran rails new customer support and we're going to be going and adding hot wire in so first thing we need to do is add hot wire rails to our gem file and then run rails hot wire install so what we're going to do is run bundle add hot wire rails now we'll add the gem to our gem file and install it and once that's done we'll run the rails hotwire install command and you'll notice here there's several different steps that this takes where it installs turbo but it will also remove turbo links so that they don't conflict because they're not compatible turbo is a replacement for turbo lynx and then we'll also enable redis and switch development cable to use reddit's as well so it does quite a few configuration changes to make sure that you're all ready to go and that's all there is to installing hotwire so that's great and we can move on to our next steps now we need to build a few models for our application and we also need to install a few things so let's run rails action or active storage colon install we're going to need that for storing our attachments from our emails and we'll have rails action text colon install to install that for storing the contents of the emails and the text in bold and everything like that that we would want and then we'll also run rails action mailbox install so that we can have the models for processing those inbound emails so once those are done we can run railsdb migrate not migrates and that will create those models and tables for us and then last but not least we're going to need to add um say devise in here so that we have a user model so we can log in so we'll run bundle add devise and then we'll run rails generate devise colon install and then rails generate devise user and we'll give our users either a name string or first and last name we'll do a name string here and then we need to start setting up our uh other models so let's generate a scaffold for a model called contact which will be kind of like our customers that we're conversing with these are not the employees so they'll be users for the employees that are on our team and then the contacts are the ones that are our customers that we're talking to and so contacts will just have a name and email you might want some other metadata on there to keep track of those but that is really it and then we can generate a scaffold for a conversation which is going to have a subject belongs to a contact uh contact belongs to so we know who we're talking to and then um we will build a post model um in order to associate each individual message with a conversation so we'll have rails generate model this time for the post the post will uh have a conversation belongs to and an author belongs to polymorphic so that this can either be a user or a contact so you could create a message sent to someone but when they reply to that it will be a different author so that would be a contact in that case instead of a user so that's why we'll do that as polymorphic and then we'll have the message id here which is actually going to be the email message id and that's how we're going to keep track of the email threads and then this is going to have a body which is rich text from action text and that's not going to create a column but it will create the association for our rich text body with action text and i believe that is all the models that we really need to get going here and we can start by playing around with this in the rail server and make sure that everything is wired up and that we can set up hotwire to actually show those new conversations in real time when they are created as well as the posts when they're created so let's go and take a look at our scaffolds here so what we really want to look at is our conversations view we're going to need to run our migrations for those new models but once that's done um the conversations view is really where we're going to be spending a lot of our time so we're going to be creating new conversations or viewing them on the index page and then when we go and look at a conversation we want to be able to see those messages appended in real time at the bottom so what we'll do is we'll change this contact over to a select so that we can contact select one of our contacts that we want to talk to so we're going to need some changes to that but let's go through our models and make sure that our conversation has many posts and that our post belongs to polymorphic and it does and all of that is good we can add as many posts to our contact as author and we can do the same thing for our user as well and that is good and then this can also be has many conversations because the contact is on the conversation so that's the recipient of the conversation or the initial one at least and we can look through that and then we can also have multiple contacts in the same conversation through posts and so we can add another association later on if we want to uh basically look for any conversation where you've been mentioned in one of the posts but we don't need that right now so let's move on from there so let's go into the contacts view and we'll create a new contact and this will be bob the builder bob at example.com we'll create that contact and now we want to be able to create a conversation with bob so we'll need to go into the conversation form html.erb and change this text field to a collection select and this will be contact.all we'll take the id for that contact and then we will use their name in that view or is the label there so we can have hello world with bob the builder create that conversation and there we go so we can go to the show conversation and if we want to link to the contact we'll say dot name link to the contact themselves so we can jump between those now and that's good but now we need to go to our conversations index and start adding some stuff here for hotwire to broadcast into this view now in our index here the conversations index is a table and we have table rows for each one of these and generally that's going to be a little bit trickier to use because because tables are actually very strict about the sub elements that you have inside of them so instead what we're going to do is we're going to say render at conversations and we will render a series of partials for each conversation because that partial is also going to be what we use to render from hot wire so let's go into our views app control or app views conversations we will have a similar to this conversation.json.jbuilder we'll have a conversation.html.erb inside of here we're going to have a div tag but we're going to use the tag.div with the id of dom id for the conversation that way we can reference this when we are deleting that conversation so we can remove that from the view and then we can have our um content here so you know let's maybe do an h4 conversation dot subject is what we want to display here we will have a link to the conversation there and that should be um really all we need for the very basics now we can go into our conversation model and we can add our belongs to our broadcasts too for hotwire and instead of doing some sort of symbol here for the association that we want to render against we actually want to pass in a lambda and we're going to give that a string that has the return value which will be the value that we render and send stuff across with action cable so then we can say inserts by pre-pend because we want these to show up at the top of the list and then we'll go into the target option which will be conversation as well conversations so that will say look for the id of conversations on the page and we're going to be using that same string on action cable for this first argument so then if we go into our index.html.erb we can say div id of conversations to match the target that we listed in the model so it's going to be looking for this id when it goes to prepend inside of here it will render out the two partial path which is conversations conversation partial and then it will insert that into the index but all of our action cable connections are created client side so we actually need a turbo stream from conversations here in order for action cable on the browser to go say hey let's go stream from that on redis and then redis will know from the client side that we have a listener and then when we create a conversation it will broadcast to that same channel and then go across to our client so this is the magic line that's going to set up your websocket connection here and if you ever want to poke around at this go into your network tab click on the cable request and this is that subscribe line you'll see the sign stream name which is a signed global id i believe and that will be sent over the turbo streams channel and set up that connection and we can go into our terminal and run conversation dot create name or subject we called it um we'll call this one testing and we will have the contact set to contact dot last and broadcasting that will create it in the database then render that partial and stream it with a background job action broadcast job and that will send it over to the client you'll see that it got inserted right here so all of that is working and working in real time and we have those conversations being displayed automatically we'll probably want to go and change the sorting so that it stays consistent and doesn't drop down at the bottom when you refresh but that's an easy one to take care of and now we can go into the conversations themselves and add our posts and have those show up in real time as well so we're going to have a very similar setup inside of our conversation show.html.erb i'm going to paste this down here at the bottom and instead of streaming from a string we're going to string stream from a variable this time so at conversation so this way we only get the posts for this conversation itself and then we'll have an idea posts and we'll render out the posts inside of here so this is going to be where those are rendered and they'll only come through that conversation so um the next piece is that we can go through and update the post model and add the view for that we're going to go into post.rb and we'll do the same broadcasts too but we'll say conversation is a symbol which matches our belongs to which also matches our turbo stream from and then we can say um the target is uh posts in this case and i believe we don't even need that that's optional i believe let's test it out real fast and that will go and set up our conversation posts section so let's go through and set up you'll notice that we don't have the post variable yet so let's go into our conversation controller and we can go into the show action and say at post equals at conversation dot posts and we'll go and add the view for that so we'll say app views posts post.html.erb and really this is just going to display it will be first off a div with the id of dom id for the post we'll have an end to close that we'll have a div with the post author name and post author email to display those and we'll have post.body that we render out which will be the action text rich text body and that will display that so we should now have no errors here and if we go to our terminal we can say conversation.last.posts dot create this will be author is contact last embody is hello and we'll create that and it should go and set that post in the database and then broadcast it as well but you'll see that we didn't get it displayed over here on the left side and that we can inspect the turbostream action prepend targeted posts so that was correct we are fine with that and this is sending over the target correctly so we just need to make sure that our broadcasting two here uh matches correctly so when we said conversation.last we actually need to be viewing that testing conversation here so here's the bob the builder post that we just created if we create a second one it will show up in this thread so we have to be a little bit careful to make sure that we're looking at the right thing and our broadcasting two ids match what we're streaming from in our views so this is an easy one that you can run into but there you go we're able to create another post and it gets appended to the bottom automatically and so our post model dot rb is a very very simple broadcast too in this case because we don't need to customize anything for that the target by default will be the plural model name so posts um all lower case and that is the default target name so that looks good we'll need to clean up our post template a little bit but we do have a functional uh hotwire set up with all of this so now when we send out emails and we receive inbound emails we can have those automatically appended and pre-pended in conversations and so on all of that will be working automatically out of the box when we implement that next step so that's it for this episode we're just setting up hot wire and our basic modeling but next episode we're going to go through and start getting into the email portion of this so i'm looking forward to that and i will talk to you guys in the next one peace
Info
Channel: GoRails
Views: 2,484
Rating: undefined out of 5
Keywords: Ruby, Ruby on Rails, Rails, Javascript, HTML, CSS, Servers, Databases, Screencast, Tutorial, Rails 6, Action Text, Active Support, Action Mailbox, Webpacker, Active Storage, Active Record, rails testing, ruby on rails testing, ruby testing, devise, rails devise
Id: WSuFaY7-q3g
Channel Id: undefined
Length: 18min 39sec (1119 seconds)
Published: Wed Apr 28 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.