< Return to Video

RailsConf 2014 - Real-time Rails with Sync by Mike Moore

  • 0:16 - 0:19
    MIKE MOORE: Hello. My name is Mike Moore,
  • 0:19 - 0:23
    and I'm gonna talk about real-time Rails with
    Sync.
  • 0:23 - 0:28
    So, hi. Hello. How's Rails Conf?
  • 0:28 - 0:31
    My name is Mike Moore. You might know be
  • 0:31 - 0:34
    as blowmage or blowmage depending on how you
    want
  • 0:34 - 0:36
    to pronounce it. It doesn't matter.
  • 0:36 - 0:39
    I am very happy to be here. I'm leaving
  • 0:39 - 0:41
    in about an hour to fly home, so I'm
  • 0:41 - 0:44
    only here for this. And I'm a hundred percent,
  • 0:44 - 0:47
    totally prepared for this. I was not up all
  • 0:47 - 0:50
    night. I did not make these slides twenty
    minutes
  • 0:50 - 0:52
    ago. Yeah.
  • 0:52 - 0:59
    So. Who likes live coding? Three people! All
    right.
  • 0:59 - 1:01
    K. We're gonna talk about Sync. Sync is a
  • 1:01 - 1:06
    fantastic little Rails engine written by Chris
    McCord. Is
  • 1:06 - 1:08
    Chris, where's Chris? Is he here? There he
    is.
  • 1:08 - 1:09
    If you don't like it - that guy right
  • 1:09 - 1:12
    there. You can find it on the GitHub. That's
  • 1:12 - 1:15
    at chrismccord slash sync.
  • 1:15 - 1:18
    So yeah. Let's do this.
  • 1:18 - 1:24
    All right. So I have a. I have an
  • 1:24 - 1:31
    app. And I'm just gonna load it up here.
  • 1:33 - 1:36
    And it's a very simple app. I was gonna
  • 1:36 - 1:39
    have a little bit more interesting app to
    demonstrate
  • 1:39 - 1:42
    this, but I ran into an issue. And maybe
  • 1:42 - 1:44
    we'll talk about that at the end. If we
  • 1:44 - 1:46
    have time.
  • 1:46 - 1:49
    But this is a very simple bloggish type of
  • 1:49 - 1:53
    application, where we've got posts, we've
    got comments, we've
  • 1:53 - 1:57
    got users, and some tags. Oh, and also, this
  • 1:57 - 2:00
    is the git repo for Sync. So please check
  • 2:00 - 2:01
    it out.
  • 2:01 - 2:04
    K, so. I want to just demonstrate this very
  • 2:04 - 2:07
    simple Rails application. We'll go look at
    a little
  • 2:07 - 2:10
    bit of code, and we're going to, we're gonna
  • 2:10 - 2:13
    add Sync to this application, and we're gonna
    turn
  • 2:13 - 2:17
    it from a very classic, kind of CRUD-y Rails
  • 2:17 - 2:20
    application into real time.
  • 2:20 - 2:25
    So. A little, one note before we start on
  • 2:25 - 2:29
    code quality, this app is intentionally unfactored.
    So there
  • 2:29 - 2:32
    is lots of places where you might apply some
  • 2:32 - 2:35
    design in an application that I have not,
    for
  • 2:35 - 2:37
    this. But, the reason for that is so that
  • 2:37 - 2:41
    I can, we can refactor it to Sync a
  • 2:41 - 2:43
    little bit easier, without having to unfactor
    it along
  • 2:43 - 2:44
    the way.
  • 2:44 - 2:46
    So, we'll go ahead and get started. So we
  • 2:46 - 2:50
    have a series of posts. And then when you
  • 2:50 - 2:53
    click on a post, you go to the post's
  • 2:53 - 2:57
    show action. On that post's show action, we've
    got
  • 2:57 - 3:01
    a series of comments. That is no different
    than
  • 3:01 - 3:06
    going to slash comments, other than it just
    looks
  • 3:06 - 3:08
    a little bit different. So. We're not gonna
    need
  • 3:08 - 3:10
    to be looking at the comments on the actual
  • 3:10 - 3:14
    resource. We're gonna be looking at it on
    the
  • 3:14 - 3:20
    post resource. And that's it. So, you know,
    say,
  • 3:20 - 3:25
    Hello RailsConf. Woo. Oh. Also, disclaimer,
    I cannot type
  • 3:25 - 3:29
    in public. So this is gonna be very interesting.
  • 3:29 - 3:30
    So I can go ahead and I can add
  • 3:30 - 3:35
    a comment. I can delete a comment, because
    it's
  • 3:35 - 3:39
    owned by me. I can go into posts that
  • 3:39 - 3:43
    I own and I can edit those posts. So
  • 3:43 - 3:46
    like that, right. Pretty simple.
  • 3:46 - 3:52
    OK. So let's bump this out a little bit.
  • 3:53 - 3:56
    So here is our application. You, same thing
    as
  • 3:56 - 3:59
    we saw before. Our home controller is the,
    the
  • 3:59 - 4:03
    home page. That showed the Jumbotron there.
    And this
  • 4:03 - 4:07
    is all very bootstrappy. I'm sorry.
  • 4:07 - 4:10
    Here's our posts controller. Almost straight
    out of the
  • 4:10 - 4:17
    box Rails resource here. Our comments controller
    is nested
  • 4:19 - 4:24
    underneath our posts controller. We've got
    a little bit
  • 4:24 - 4:29
    of additional calls here for access. Those
    are defined
  • 4:29 - 4:33
    in helpers. This may not be how you would
  • 4:33 - 4:36
    do this in a real application, but for demonstration
  • 4:36 - 4:39
    purposes it, it fits the need. And I can
  • 4:39 - 4:43
    use these methods in the controller and also
    in
  • 4:43 - 4:45
    the views.
  • 4:45 - 4:48
    OK. So let's take a look at the routes.
  • 4:48 - 4:50
    So you see we're not, we're not, we're not
  • 4:50 - 4:56
    cheating. So we've got nested comments under
    posts. We've
  • 4:56 - 4:58
    also got tags. Let's take a look at tags
  • 4:58 - 5:02
    real quick. Tags are just a string attached
    to
  • 5:02 - 5:05
    these various posts, and so if you click on
  • 5:05 - 5:08
    the Rails tag, you see there are three of
  • 5:08 - 5:11
    the four posts that are tagged with Rails.
    And
  • 5:11 - 5:15
    then there is a list. So.
  • 5:15 - 5:19
    Let's say that we have this application, and
    we
  • 5:19 - 5:22
    want to make it more awesome than it is
  • 5:22 - 5:25
    today. One of the things we really want is
  • 5:25 - 5:29
    we want to approximate what some of the apps
  • 5:29 - 5:34
    that are using heavy Javascript MVC frameworks
    are accomplishing
  • 5:34 - 5:38
    with, with their responsiveness, and just
    kind of like
  • 5:38 - 5:41
    updating the UI because something changed.
  • 5:41 - 5:46
    And so instead of basically rewriting our
    entire frontend,
  • 5:46 - 5:49
    our entire presentation layer, and then also
    creating an
  • 5:49 - 5:54
    API to support that Javascript presentation
    layer, it's my
  • 5:54 - 5:58
    conjecture that, conj- it's my assertion here
    that we
  • 5:58 - 6:02
    can use Rails the way Rails is intended to
  • 6:02 - 6:06
    be used, but still gain a good sub, a
  • 6:06 - 6:10
    good, large portion of, of this type of functionality.
  • 6:10 - 6:11
    So.
  • 6:11 - 6:14
    Let's go ahead and jump in.
  • 6:14 - 6:18
    All right, so the first thing we want to
  • 6:18 - 6:22
    do is open the gemfile and we want to
  • 6:22 - 6:28
    add a few gems. The first one is faye.
  • 6:28 - 6:29
    And the reason we need to add faye is
  • 6:29 - 6:34
    just for, for development. So we're gonna
    use faye
  • 6:34 - 6:36
    for our browser to talk over websocket back
    to
  • 6:36 - 6:41
    the server. And then faye also needs thin,
    but
  • 6:41 - 6:44
    we don't like thin very much, so we're gonna
  • 6:44 - 6:50
    not require it by default. And then the last
  • 6:50 - 6:53
    one is Sync. K.
  • 6:53 - 6:58
    So we'll bundle install that. Told you I couldn't
  • 6:58 - 7:02
    type. There you go.
  • 7:02 - 7:04
    So now we've got, we've added sync to the
  • 7:04 - 7:08
    application. We need to go a couple steps
    further.
  • 7:08 - 7:10
    The first is, in our application file, we
    need
  • 7:10 - 7:15
    to add the Javascript for Sync. And so this
  • 7:15 - 7:18
    will be loaded as part of our normal application
  • 7:18 - 7:22
    Javascript everywhere. It will get pulled
    in by the,
  • 7:22 - 7:27
    the, by the asset pipeline. And then also
    we
  • 7:27 - 7:31
    need to go into our layout, our main application
  • 7:31 - 7:35
    layout, and there's another Javascript tag
    that we need
  • 7:35 - 7:41
    to add. And that is going to be, we're
  • 7:41 - 7:46
    gonna use a little helper from Sync, adapter
    Javascript
  • 7:46 - 7:51
    url.
  • 7:51 - 7:53
    And we'll talk about what all these mean,
    hopefully
  • 7:53 - 7:57
    by the end of this. OK. Now we're good
  • 7:57 - 8:00
    to go. So what we need to do, before
  • 8:00 - 8:04
    we do anything else, is we need to start
  • 8:04 - 8:09
    up faye to run our web socket connections.
    So
  • 8:09 - 8:11
    we can do that pretty easily. We can just
  • 8:11 - 8:15
    say rack up Sync.
  • 8:15 - 8:22
    Oh. I'm sorry. One more thing. We need to
  • 8:24 - 8:31
    just take a look at our generators. Oh, gosh.
  • 8:31 - 8:35
    K. There is now this install generator that
    was
  • 8:35 - 8:39
    added by, by sync, so let's go ahead and
  • 8:39 - 8:42
    run that generator. That will create a rackup
    file
  • 8:42 - 8:44
    and a configuration file.
  • 8:44 - 8:51
    So. Now that we have that, we can, we
  • 8:51 - 8:55
    can run this. Now this is going to run
  • 8:55 - 8:58
    faye in the background, and then here we can
  • 8:58 - 9:02
    just run our application. Come back over here
    and
  • 9:02 - 9:04
    refresh and nothing has changed, but it all
    continues
  • 9:04 - 9:08
    to work. So faye is running, but we're not
  • 9:08 - 9:10
    actually talking to it. But we know that it,
  • 9:10 - 9:14
    it's up. So. That's the important first step.
  • 9:14 - 9:17
    I don't particularly like having to open up
    two
  • 9:17 - 9:20
    consoles, so one of the things I will do
  • 9:20 - 9:23
    is I'm gonna create a new file called, a
  • 9:23 - 9:29
    new proc file, and then inside of it I'm
  • 9:29 - 9:36
    gonna have a web entry. So you can't see
  • 9:38 - 9:40
    this, but this, I have to scooch down to,
  • 9:40 - 9:42
    so you can hear me, and it's killing my
  • 9:42 - 9:42
    back.
  • 9:42 - 9:49
    AUDIENCE: I think you can just stand up and
  • 9:49 - 9:51
    do it.
  • 9:51 - 9:58
    M.M.: Are you sure? All right. Exec, so rackup,
  • 9:59 - 10:06
    sync conf, sync ru. OK.
  • 10:06 - 10:07
    The other thing we need to do is come
  • 10:07 - 10:14
    back over here and add foreman. K. So, so
  • 10:17 - 10:20
    install that. Foreman is a gem written by
    Heroku,
  • 10:20 - 10:22
    and so if you have lots of services that
  • 10:22 - 10:26
    you are coordinating, Foreman's a good way
    to, to
  • 10:26 - 10:28
    start all of those. So now instead of going
  • 10:28 - 10:32
    to multiple terminals to open up, open this
    up,
  • 10:32 - 10:36
    I can just say Foreman start, and it will
  • 10:36 - 10:40
    start both. So that's kind of handy.
  • 10:40 - 10:43
    All right. Let's take a look at one of
  • 10:43 - 10:49
    these, one of these pages. What I want is
  • 10:49 - 10:50
    I want to be able to come over here
  • 10:50 - 10:53
    onto this page and I want to add a
  • 10:53 - 10:55
    new comment, and then I want people to see
  • 10:55 - 11:02
    it as soon as it shows up, right.
  • 11:02 - 11:05
    So if I say see me, my, my browser
  • 11:05 - 11:09
    refreshes. But all of these browsers over
    here won't
  • 11:09 - 11:16
    necessarily. So let's go to this guy. K.
  • 11:24 - 11:31
    So if I, for example, delete this one, it
  • 11:34 - 11:35
    still shows up in these other browsers. And
    I
  • 11:35 - 11:38
    would really like it if it would disappear
    as
  • 11:38 - 11:45
    soon as we ask it to. So let's make
  • 11:45 - 11:49
    that happen. To do that, we are going to
  • 11:49 - 11:55
    register our ActiveRecord models to be synced
    in browsers.
  • 11:55 - 11:57
    And Sync is going to take care of all
  • 11:57 - 12:00
    of the communication from our Rails application,
    all the
  • 12:00 - 12:02
    way down to the browsers for us.
  • 12:02 - 12:05
    So, to do that, there's a couple of things
  • 12:05 - 12:10
    we want to change. First is, we map up
  • 12:10 - 12:14
    our comment model. And we're gonna add this
    little
  • 12:14 - 12:17
    declaration called sync_all to it. This is
    going to
  • 12:17 - 12:20
    insert the sync DSL into the model. So now
  • 12:20 - 12:22
    whenever the model changes, it will try to
    notify
  • 12:22 - 12:26
    the browsers that something has changed. We
    also, we
  • 12:26 - 12:31
    need to open up our controller, and we need
  • 12:31 - 12:38
    to enable sync here as well. K.
  • 12:38 - 12:41
    And this is, again, just to, so the controller
  • 12:41 - 12:43
    knows to look for all of the messages from
  • 12:43 - 12:49
    the models that something has updated and
    respond appropriately.
  • 12:49 - 12:54
    Let's take a look at the post show action.
  • 12:54 - 12:58
    Like I said, this is a mess of HTML.
  • 12:58 - 13:00
    This is not necessarily how I would do it,
  • 13:00 - 13:03
    but this is how it is. We've got kind
  • 13:03 - 13:06
    of two main areas of the page. The first
  • 13:06 - 13:08
    is at the top, where you've got all the
  • 13:08 - 13:12
    content for the blog post. So the title, the
  • 13:12 - 13:16
    user, those tags that are on the, the blog
  • 13:16 - 13:20
    post. Some editing links, if they are there,
    and
  • 13:20 - 13:23
    then also the markdown of the body. OK.
  • 13:23 - 13:26
    Then after that we've got our comments section,
    which
  • 13:26 - 13:29
    is going to iterate through the comments,
    and because
  • 13:29 - 13:32
    we're showing, and then we're rendering a
    partial for
  • 13:32 - 13:37
    the comment. And then after that, there's
    also another
  • 13:37 - 13:40
    area to add a new comment, if you can.
  • 13:40 - 13:41
    So if you're logged in, you should be able
  • 13:41 - 13:44
    to comment. And if you're not logged in, you
  • 13:44 - 13:48
    shouldn't. And that's what that add comment
    helper there
  • 13:48 - 13:50
    is guarding for us.
  • 13:50 - 13:52
    So, we want to make, we just want to
  • 13:52 - 13:55
    make this sync. It's pretty easy. What we're
    gonna
  • 13:55 - 13:58
    do, we're gonna change this from render to
    sync
  • 13:58 - 14:05
    partial, and then we're gonna say that our
    resource
  • 14:07 - 14:09
    is our comment. So we've made it just a
  • 14:09 - 14:12
    little more verbose than what it was before,
    but
  • 14:12 - 14:14
    sync needs that.
  • 14:14 - 14:17
    The next thing we're gonna do is we're gonna
  • 14:17 - 14:21
    add a new directory under app/views called
    sync, and
  • 14:21 - 14:26
    under sync we're gonna add another folder
    called comments.
  • 14:26 - 14:28
    And under comments, we're gonna add a new
    file,
  • 14:28 - 14:32
    and that's gonna be called comments dot html
    dot
  • 14:32 - 14:35
    erb. That's gonna be our partial, K.
  • 14:35 - 14:39
    So, when we say sync partial here, instead
    of
  • 14:39 - 14:41
    looking at our normal template, it's gonna
    go look
  • 14:41 - 14:44
    for the one in the sync directory. And for
  • 14:44 - 14:48
    the most part, we're just gonna take our trusty
  • 14:48 - 14:51
    old partial that we're using right now and
    copy
  • 14:51 - 14:53
    and paste that. We can kind of just trim
  • 14:53 - 14:55
    some of this out. One of the caveats of
  • 14:55 - 15:00
    using sync is that we can't really do stuff
  • 15:00 - 15:03
    like this. We can't ask about the current
    context
  • 15:03 - 15:05
    in which it's running, because this will get
    pushed
  • 15:05 - 15:08
    out to everybody. So this, the same strategy
    you
  • 15:08 - 15:13
    have for caching templates, caching partials
    within your application,
  • 15:13 - 15:16
    you're gonna apply that same strategy to the
    real
  • 15:16 - 15:17
    time updates as well.
  • 15:17 - 15:20
    And so stuff like this is probably just, just
  • 15:20 - 15:23
    gonna have to go, right. We can have the
  • 15:23 - 15:25
    user name, we have have what the body is.
  • 15:25 - 15:29
    But we really can't have all those editing
    options.
  • 15:29 - 15:33
    AUDIENCE: [indecipherable - 00:15:35]
  • 15:33 - 15:40
    M.M.: Oh, did I? Thank you.
  • 15:41 - 15:48
    Let's rename this. So comment instead of comments.
    So
  • 15:49 - 15:52
    that's our first step. The next change we
    want
  • 15:52 - 15:54
    to make is, whenever a new comment comes,
    we
  • 15:54 - 15:58
    want that to show up underneath, and so instead
  • 15:58 - 16:00
    of calling sync, we're gonna call sync.new.
    This is
  • 16:00 - 16:04
    going to watch for new comments.
  • 16:04 - 16:09
    In here, the resource is going to have to
  • 16:09 - 16:14
    be a comment dot new, is that right? We
  • 16:14 - 16:20
    can probably go a little bit further and say
  • 16:20 - 16:24
    posts.comment dot new. K. All right.
  • 16:24 - 16:26
    So that's not a lot of changes. What we've
  • 16:26 - 16:28
    done is we've added sync to the repository,
    to
  • 16:28 - 16:33
    the application. We've registered all the
    Javascript. We've went
  • 16:33 - 16:37
    in, went ahead, moved some of our html from
  • 16:37 - 16:41
    the original locations to a new location under
    sync
  • 16:41 - 16:45
    and instead of calling render, we're gonna
    call sync
  • 16:45 - 16:46
    and sync new.
  • 16:46 - 16:47
    AUDIENCE: [indecipherable - 00:16:47]
  • 16:47 - 16:49
    M.M.: What's that?
  • 16:49 - 16:50
    AUDIENCE: [indecipherable - 00:16:49]
  • 16:50 - 16:55
    M.M.: Post, yes. Thank you. Live coding, ladies
    and
  • 16:55 - 16:55
    gentlemen.
  • 16:55 - 17:00
    Yeah. I transposed the plural. There you go.
  • 17:00 - 17:01
    AUDIENCE: Pair programming to scale.
  • 17:01 - 17:02
    M.M.: Pair programming to scale. All right.
  • 17:02 - 17:03
    So let's see if this works. What I'm gonna
  • 17:03 - 17:05
    do is I'm gonna refresh this page. I'm gonna
  • 17:05 - 17:07
    refresh this page. I'm gonna refresh this
    page. Now
  • 17:07 - 17:13
    Firefox is not logged in. Safari here is logged
  • 17:13 - 17:16
    in here by Stanley, who's back there somewhere,
    and
  • 17:16 - 17:20
    then Chrome is logged in by me. So let's
  • 17:20 - 17:22
    see if this works. Who wants to place a
  • 17:22 - 17:23
    bet?
  • 17:23 - 17:25
    Does this work? Anybody know?
  • 17:25 - 17:30
    All right. Let's see if it works. All right.
  • 17:30 - 17:37
    There we go. Does this work? K. Yay!
  • 17:39 - 17:42
    So what's nice about this approach is that
    this
  • 17:42 - 17:44
    is gonna go out no matter how many clients
  • 17:44 - 17:50
    you've got connected, theoretically. Every
    time your, your assets
  • 17:50 - 17:52
    change, your resources change in your application,
    they can
  • 17:52 - 17:55
    be notified in real time. K.
  • 17:55 - 17:56
    And we didn't have to write a whole bunch
  • 17:56 - 17:59
    of Javascript. We didn't have to change how
    we
  • 17:59 - 18:02
    were architecting our presentation layer.
    We're gonna use the,
  • 18:02 - 18:08
    the same infrastructure that we're using today.
    All right.
  • 18:08 - 18:12
    OK. Now, because of this, I kind of lost
  • 18:12 - 18:16
    my ability to, to edit. And I would like
  • 18:16 - 18:19
    to have that back. So what I want to
  • 18:19 - 18:26
    do is, in this loop, where we're saying, you
  • 18:26 - 18:29
    know, we're gonna add this missing partial,
    what I
  • 18:29 - 18:30
    really want to do is I want to say,
  • 18:30 - 18:37
    if you can edit the comment, right. And that's
  • 18:37 - 18:42
    current user. What I really want to say is
  • 18:42 - 18:45
    that if I can edit, I want to have
  • 18:45 - 18:52
    the same partial I had before, right. But,
    if
  • 18:53 - 18:57
    I can't, then I want to use the one
  • 18:57 - 19:00
    that is going to be synced. K.
  • 19:00 - 19:07
    K. So, it's a small change. But what it's,
  • 19:09 - 19:13
    what it's saying is, is that, if I have
  • 19:13 - 19:15
    permissions to edit it, I don't want it to
  • 19:15 - 19:16
    be syncing, I don't want to be notified if
  • 19:16 - 19:19
    it changes, because I am likely the browser
    that's
  • 19:19 - 19:21
    gonna be changing it. And, and I really want
  • 19:21 - 19:25
    the tools to be able to edit and delete.
  • 19:25 - 19:28
    So I'm gonna just come back here and refresh
  • 19:28 - 19:32
    this UI, and you'll notice now, because of
    that,
  • 19:32 - 19:34
    I have my tools back. My edit and delete.
  • 19:34 - 19:38
    So I can come back over here and say
  • 19:38 - 19:45
    yes, it does work. See, that updates there.
    It
  • 19:46 - 19:51
    looks like we've got a little bug.
  • 19:51 - 19:56
    And then eventually I can actually delete
    it as
  • 19:56 - 20:03
    well. And it gets rid of it. K.
  • 20:04 - 20:09
    And there's another bug with this. Do you
    guys
  • 20:09 - 20:15
    want to see what it is? It's pretty fun.
  • 20:15 - 20:19
    Here is a, well, let's go to this one.
  • 20:19 - 20:20
    Here is a blog post that doesn't have any
  • 20:20 - 20:23
    comments yet. I'm gonna go onto this different
    blog
  • 20:23 - 20:28
    post, right, and, say we gotta bug. When I
  • 20:28 - 20:31
    do that, my comment is showing up on this
  • 20:31 - 20:34
    different blog post, right. Because it's,
    right now we're
  • 20:34 - 20:36
    looking for all comments whenever it gets
    updated, we're
  • 20:36 - 20:38
    gonna add it to this page. So what we
  • 20:38 - 20:40
    need to do is we need to scope these
  • 20:40 - 20:43
    comments to this page. So let's add that really
  • 20:43 - 20:44
    quick.
  • 20:44 - 20:50
    We're gonna come back here to, come back here
  • 20:55 - 20:58
    to our comment model, and we're gonna add
    a
  • 20:58 - 21:04
    new scope. Now, this is gonna be different
    than
  • 21:04 - 21:08
    a normal scope. Might be a redundancy, but
    sync
  • 21:08 - 21:13
    needs it. So let's add it, called by_posts.
    And
  • 21:13 - 21:15
    it's gonna take a lambda, and we're gonna
    give
  • 21:15 - 21:21
    it a post and we're gonna say where post
  • 21:21 - 21:24
    id is post id. K.
  • 21:24 - 21:31
    K. So we've just added a scope for post.
  • 21:32 - 21:38
    Then we're gonna come over here into our sync
  • 21:38 - 21:45
    partials. And we're going to add that scope
    here.
  • 21:46 - 21:53
    So let's, let's see scope dot by_posts. And
    let's
  • 22:00 - 22:07
    also add that to this one. K.
  • 22:07 - 22:12
    So now if we refresh this, come over here,
  • 22:12 - 22:16
    and now I'm logged in as Stanley. I say,
  • 22:16 - 22:20
    oh hi. It shows up here, which is what
  • 22:20 - 22:21
    we expect, but on this other one it does
  • 22:21 - 22:24
    not, K. And if I refresh this we'll get
  • 22:24 - 22:29
    rid of that comment. So scoping is, is easy
  • 22:29 - 22:34
    as declaring a new scope on your model, in
  • 22:34 - 22:37
    the same syntax that we're using for normal
    scopes.
  • 22:37 - 22:40
    And then whenever we render out our partials,
    we
  • 22:40 - 22:42
    just have to, we have to reference that scope.
  • 22:42 - 22:42
    M.M.: Why do we need what?
  • 22:48 - 22:53
    M.M.: The scope in both? Cause there are two
  • 22:53 - 22:56
    different partials. It, it would be possible
    to-
  • 22:56 - 22:59
    AUDIENCE: [indecipherable - 00:22:59]
  • 22:59 - 23:03
    M.M.: No. It affects both. The scope affects
    both.
  • 23:03 - 23:05
    The reason why there are two partials, here,
    is
  • 23:05 - 23:09
    that whenever a new comment comes into existence,
    we
  • 23:09 - 23:10
    want that to be listed. So we can move
  • 23:10 - 23:17
    that around, theoretically, I believe, if.
    Whoa.
  • 23:22 - 23:29
    Nevermind. Let's not touch that. Live coding.
  • 23:32 - 23:39
    All right. So sync is a pretty cool little
  • 23:39 - 23:41
    library. It does quite a lot for us. What
  • 23:41 - 23:44
    it's going to do, is it's going to hold
  • 23:44 - 23:48
    a connection via web socket to a server, and
  • 23:48 - 23:51
    then it's going to put mechanisms within Rails
    to
  • 23:51 - 23:55
    talk to that, that web socket, and then when
  • 23:55 - 23:59
    our resources change, it will render those
    templates and
  • 23:59 - 24:01
    push that out to that web socket, which the
  • 24:01 - 24:04
    clients will then pull down, K. So without
    re,
  • 24:04 - 24:09
    without rearchitecting our presentation tier,
    we are able to
  • 24:09 - 24:12
    take advantage of real time, and able to do
  • 24:12 - 24:16
    it without a major change to how we're organizing
  • 24:16 - 24:19
    or architecting our templates, our files.
  • 24:19 - 24:23
    We can go just a little bit further, as
  • 24:23 - 24:29
    well. So let's open a Rails console, K, and
  • 24:29 - 24:36
    we'll say. Just get, just a comment out of
  • 24:37 - 24:44
    here. All right. So I got this comment right
  • 24:44 - 24:46
    here, which is Jason saying that he's watching,
    but
  • 24:46 - 24:48
    he's kind of on a delay because he's not
  • 24:48 - 24:51
    actually in the room, K.
  • 24:51 - 24:55
    What we can say here is sync model dot
  • 24:55 - 24:59
    enable, and this will allow all changes that
    happen
  • 24:59 - 25:02
    within our process, that's not running on
    the web
  • 25:02 - 25:04
    server, still a Rails process, but we're not
    actually
  • 25:04 - 25:07
    on running on the web server. It's a separate
  • 25:07 - 25:09
    process. Maybe a background job. But now all
    of
  • 25:09 - 25:12
    our changes that we make can also be reflected
  • 25:12 - 25:14
    in real time as well.
  • 25:14 - 25:21
    So let's pull this guy over. And watch that
  • 25:21 - 25:25
    happen. So we can change this to, what should
  • 25:25 - 25:32
    Jason say? Say, I don't know, real time. K,
  • 25:35 - 25:38
    so let's pull him out. You see that his
  • 25:38 - 25:41
    text is right here. I'm watching, kind of.
    When
  • 25:41 - 25:44
    I call save it will change, and it updates
  • 25:44 - 25:51
    right here, in real time. And duplicate. Why?
    Chris?
  • 25:51 - 25:52
    Why?
  • 25:52 - 25:53
    Applettes.
  • 25:53 - 25:58
    AUDIENCE: Wait till afterwards.
  • 25:58 - 26:03
    M.M.: Afterwards? All right.
  • 26:03 - 26:06
    OK. Let's continue and add this to some of
  • 26:06 - 26:12
    the other pages as well. So let's go to
  • 26:12 - 26:14
    post. Let's do the same thing. We want to
  • 26:14 - 26:21
    sync our posts as well. And our posts controller,
  • 26:21 - 26:25
    we want to enable sync here as.
  • 26:25 - 26:31
    Enable sync on our post controller and in
    our
  • 26:31 - 26:34
    posts model. So let's go ahead and take a
  • 26:34 - 26:40
    look at our post index page. Our index page,
  • 26:40 - 26:41
    where we're listing all the posts, we're gonna
    go
  • 26:41 - 26:46
    through and render the post. And then, if
    we
  • 26:46 - 26:51
    have, if we can, we'll add, we'll have a
  • 26:51 - 26:54
    button to add a new post. If we look
  • 26:54 - 26:57
    at that post partial, you notice here, again,
    we've
  • 26:57 - 27:00
    got some logic in here determining whether
    or not
  • 27:00 - 27:02
    we can edit it, or whether or not we
  • 27:02 - 27:04
    can remove it.
  • 27:04 - 27:07
    So this logic is problematic when we're talking
    about
  • 27:07 - 27:10
    a cache template that's gonna get pushed out
    to
  • 27:10 - 27:12
    everybody, cause not everybody's gonna have
    the same amount
  • 27:12 - 27:14
    of permissions. So what we'll have to do is
  • 27:14 - 27:17
    we'll have to just take that out. And I'm
  • 27:17 - 27:20
    gonna take it out and put it into the
  • 27:20 - 27:22
    index template.
  • 27:22 - 27:26
    Well. Actually, I'm just gonna take it out
    of,
  • 27:26 - 27:31
    of this view altogether. So, again, in order
    to
  • 27:31 - 27:34
    change our template from a static template
    to a
  • 27:34 - 27:41
    real time template, we're gonna say sync and
    partial
  • 27:44 - 27:49
    is a post. And then our resource is also
  • 27:49 - 27:54
    gonna be that same post, and then, if we
  • 27:54 - 27:57
    get a new post, it just lists him down
  • 27:57 - 28:00
    below. We don't, probably don't need to scope
    on
  • 28:00 - 28:04
    this one. The big problem we have is all
  • 28:04 - 28:09
    of this edit information. So let's go over
    here
  • 28:09 - 28:12
    to posts and get rid of that guy. So
  • 28:12 - 28:16
    I'm just gonna remove some, some code here.
    I'm
  • 28:16 - 28:19
    gonna remove all of this editing. Anything
    that's gonna
  • 28:19 - 28:21
    talk to current user, the current request
    is not
  • 28:21 - 28:27
    gonna work. So let's get rid of that.
  • 28:27 - 28:34
    And now let's take a look at, take a
  • 28:37 - 28:44
    look at our, our post pages. I don't know
  • 28:45 - 28:50
    what that is.
  • 28:50 - 28:52
    We're asking for posts, it doesn't exist outside
    of
  • 28:52 - 28:57
    that block. So we're gonna say post dot new.
  • 28:57 - 29:04
    OK. So, again, user not logged in, user logged
  • 29:05 - 29:09
    in, and as a different user logged in. So
  • 29:09 - 29:12
    if I come over here, I want to add
  • 29:12 - 29:18
    new post. See if it works. And let's add
  • 29:23 - 29:23
    that.
  • 29:23 - 29:26
    So, Stanley added this post. It shows up immediately
  • 29:26 - 29:29
    on, on Mike's browser. And it also shows up
  • 29:29 - 29:33
    in the not logged in browser. Let's come over
  • 29:33 - 29:40
    here. We'll, we'll say congrats. Now.
  • 29:46 - 29:49
    This browser over the right, the comment is
    not
  • 29:49 - 29:56
    updating, right. Let's go back over here.
    So here,
  • 29:56 - 30:03
    we've got one comment. Stanley says, I know.
    And
  • 30:04 - 30:08
    that, that one comment here is still not updated.
  • 30:08 - 30:11
    So we've got changes happening on a sub-resource,
    but
  • 30:11 - 30:15
    it's not changing our template. Thankfully
    there's a really
  • 30:15 - 30:20
    nice DSL to make that happen. So we'll go
  • 30:20 - 30:23
    to our comment controll- or, comment object,
    and we'll
  • 30:23 - 30:29
    say sync touch post. K.
  • 30:29 - 30:31
    So this is similar to normal touch. If you
  • 30:31 - 30:35
    want, have a resource that you want to touch
  • 30:35 - 30:38
    through an association whenever it updates,
    it works just
  • 30:38 - 30:41
    the same, only it's a special one that'll
    work
  • 30:41 - 30:46
    for sync. So let's save that and refresh all
  • 30:46 - 30:52
    of these browsers. K. So now they all have
  • 30:52 - 30:55
    two comments. OK.
  • 30:55 - 31:02
    I come over here. Let's have Stanley add one
  • 31:02 - 31:09
    more, add one more comment. Man, Chris. Now
    the
  • 31:09 - 31:15
    comments are updating multiple times. I'm
    curious to why
  • 31:15 - 31:20
    that is. It wasn't doing that an hour ago.
  • 31:20 - 31:27
    What did I miss? OK.
  • 31:28 - 31:32
    There's one more, there's one more review
    of posts
  • 31:32 - 31:38
    here, and that is the actual post page. So
  • 31:38 - 31:45
    we can edit this. So let's say it sort
  • 31:45 - 31:49
    of works, but now this page isn't updating
    and
  • 31:49 - 31:52
    this page isn't updating, right. So we, I've
    updated
  • 31:52 - 31:55
    this post, but the other browsers aren't updating
    on
  • 31:55 - 31:57
    the show page. The reason for that is because
  • 31:57 - 32:00
    we're not syncing the template on that page.
    So
  • 32:00 - 32:04
    really quick we'll see, we'll show you just
    how
  • 32:04 - 32:06
    easy it is to do that. We'll come over
  • 32:06 - 32:10
    here to show. We have this same information
    where
  • 32:10 - 32:14
    we're pawing out all of these links determining,
    you
  • 32:14 - 32:17
    know, whether or not we can edit. I'm gonna
  • 32:17 - 32:19
    punt on that. I'm just gonna put that down
  • 32:19 - 32:23
    below. So it's not gonna be part of any
  • 32:23 - 32:25
    template. So if you hit this page and you
  • 32:25 - 32:28
    can edit it, we're going to show you those
  • 32:28 - 32:32
    links. But it's gonna be outside of the, outside
  • 32:32 - 32:34
    of the, the partial.
  • 32:34 - 32:39
    So I'm just gonna sit. We're gonna sync a
  • 32:39 - 32:46
    new partial and it's gonna be called, oh my
  • 32:49 - 32:56
    gosh. I cannot type. It really is so uncomfortable.
  • 32:59 - 33:02
    So a new partial, we're gonna call this postfull,
  • 33:02 - 33:06
    because we have the full body embedded in
    it.
  • 33:06 - 33:09
    And the resource is going to be that post
  • 33:09 - 33:13
    object. And then that's really it. We come
    back
  • 33:13 - 33:17
    here to our sync directory under posts, create
    a
  • 33:17 - 33:24
    new file, and we'll save this as postfull.
  • 33:27 - 33:31
    And then we'll come back, restart all of these
  • 33:31 - 33:38
    browsers, and come back here and edit this
    and
  • 33:40 - 33:47
    so it really does work. What?
  • 33:47 - 33:52
    What am I missing?
  • 33:52 - 33:57
    AUDIENCE: [indecipherable - 00:34:01]
  • 33:57 - 34:04
    M.M.: I did refresh the browsers. Let's refresh
    it
  • 34:05 - 34:08
    one more time.
  • 34:08 - 34:13
    AUDIENCE: Did you try rebooting?
  • 34:13 - 34:18
    M.M.: Huh. All right. Again. It worked an
    hour
  • 34:18 - 34:19
    ago.
  • 34:19 - 34:25
    So, that's sync. I'm out of time. But we've
  • 34:25 - 34:30
    used this on some internal apps dealing with
    monitoring.
  • 34:30 - 34:34
    And instead of pulling, continually asking
    for new information,
  • 34:34 - 34:37
    just organizing a Rails app like you always
    have
  • 34:37 - 34:40
    with templates and having those templates
    update whenever resource
  • 34:40 - 34:44
    is changed has been just a really, really
    great,
  • 34:44 - 34:47
    fantastic thing. There are caveats. It's a
    little touchy,
  • 34:47 - 34:49
    as you can see. But it's definitely been getting
  • 34:49 - 34:52
    better over time.
  • 34:52 - 34:53
    I would just like to leave you with this
  • 34:53 - 34:58
    little pitch, that Rails has benefited, over
    the years,
  • 34:58 - 35:05
    from being first to, to popularize certain
    approaches for
  • 35:05 - 35:07
    web development. It was there at the very
    beginning
  • 35:07 - 35:09
    with Ajax. It was there are the very beginning
  • 35:09 - 35:13
    with REST. I, I strongly feel that if we
  • 35:13 - 35:16
    are not able to do real time information within
  • 35:16 - 35:20
    Rails that people will move on from Rails.
    And
  • 35:20 - 35:22
    I totally think that you don't need to. I
  • 35:22 - 35:25
    know that there's a lot of functionality that
    is
  • 35:25 - 35:27
    very difficult to do with Rails as it is
  • 35:27 - 35:29
    today, and so people are looking outside of
    Rails
  • 35:29 - 35:33
    for the presentation. But there are so many
    advantages
  • 35:33 - 35:37
    to rendering your html on the server that
    we
  • 35:37 - 35:38
    just need to think a little bit differently
    and
  • 35:38 - 35:40
    a little bit better about it.
  • 35:40 - 35:42
    So, I'll open it up to questions.
Title:
RailsConf 2014 - Real-time Rails with Sync by Mike Moore
Description:

more » « less
Duration:
36:11

English subtitles

Revisions