< Return to Video

RailsConf 2014 - Web Applications with Ruby (not Rails) by David Padilla

  • 0:17 - 0:19
    DAVID PADILLA: All right. Let's get started.
  • 0:19 - 0:22
    Hello everyone. My name is David Padilla.
  • 0:22 - 0:26
    You can find me at dabit. That's my user name
  • 0:26 - 0:28
    on Twitter, on GitHub, and basically
  • 0:28 - 0:32
    everything that matters. Hold on.
  • 0:32 - 0:34
    I work for a company called Crowd Interactive,
    which
  • 0:34 - 0:38
    is a Ruby on Rails consultancy based in Mexico.
  • 0:38 - 0:43
    We also organize the only conference down
    there that
  • 0:43 - 0:46
    takes topics like Ruby, JavaScript and all
    that. You
  • 0:46 - 0:49
    can go to that website if you want more
  • 0:49 - 0:49
    info.
  • 0:49 - 0:52
    And I'm here to talk to you, or more
  • 0:52 - 0:55
    like to, sort of, how to write web applications
  • 0:55 - 0:58
    with Ruby but not with Rails, nor Sinatra
    nor
  • 0:58 - 1:01
    Padrino nor any kind of frameworks.
  • 1:01 - 1:04
    First, I want to give you a little bit
  • 1:04 - 1:07
    of background of, of, of why I'm here or
  • 1:07 - 1:12
    where this, where this talk came from. So,
    I
  • 1:12 - 1:19
    basically invented MVC on ASP Classic. I don't
    know
  • 1:19 - 1:22
    if you guys are old enough to hear about
  • 1:22 - 1:26
    ASP Classic. Those were the good days.
  • 1:26 - 1:30
    So I invented MVC on ASP. Although not really.
  • 1:30 - 1:33
    Not formally. But, when I was working back
    then,
  • 1:33 - 1:35
    my first job, it was ASP, and I was
  • 1:35 - 1:38
    doing things like this. I remember, they threw
    me
  • 1:38 - 1:40
    into a project that had code like this, that
  • 1:40 - 1:43
    was like a page. They want that ASP. And
  • 1:43 - 1:45
    we had all that code at the beginning where
  • 1:45 - 1:48
    you set up your connection and, and everything
    relevant,
  • 1:48 - 1:51
    and then on the, on the body of the,
  • 1:51 - 1:53
    of the, of the page, you have, like, the
  • 1:53 - 1:57
    dynamic stuff and, and, and you ran SQL queries
  • 1:57 - 2:00
    and all that. And then whenever we needed
    to
  • 2:00 - 2:04
    do another page like this, we would just copy
  • 2:04 - 2:08
    all the code into page two, dot asp, and
  • 2:08 - 2:11
    just change what's relevant. Right? But everything
    was copied
  • 2:11 - 2:13
    and pasted into page and page and page, which
  • 2:13 - 2:16
    was kind of odd.
  • 2:16 - 2:17
    So when I, when I, when I began working
  • 2:17 - 2:19
    with this, I was wondering like, how, how
    can
  • 2:19 - 2:23
    this be possible. What happens, like, it was,
    it
  • 2:23 - 2:25
    was painful to change something on the layout,
    for
  • 2:25 - 2:27
    example. Just the page title, because you
    had to
  • 2:27 - 2:32
    go page one, one by one to change whatever
  • 2:32 - 2:34
    needed to be changed, and it made no sense
  • 2:34 - 2:35
    to me.
  • 2:35 - 2:38
    So I came up with some sort of hack.
  • 2:38 - 2:40
    I changed the code to do something like this.
  • 2:40 - 2:43
    I discovered there was some sort of include,
    so
  • 2:43 - 2:47
    I said, I, I put all my database stuff
  • 2:47 - 2:49
    in a single file. And then I decided to
  • 2:49 - 2:53
    use the query string to drive to the application
  • 2:53 - 2:55
    and do something like this. So I only had
  • 2:55 - 2:58
    index dot asp, and then through query string
    I
  • 2:58 - 3:02
    said page, product list. And then it, with
    a,
  • 3:02 - 3:04
    with a fancy case, I will say, OK, if
  • 3:04 - 3:07
    it says products then you have to call products
  • 3:07 - 3:09
    dot asp. If it's another page, call this one
  • 3:09 - 3:11
    and so on. And this made things easier. If
  • 3:11 - 3:13
    I needed to change something on the layout,
    you
  • 3:13 - 3:16
    will just switch it in index dot asp and
  • 3:16 - 3:17
    not the whole application.
  • 3:17 - 3:20
    Now, before you judge me for this code, let
  • 3:20 - 3:22
    me remind you that it was the year 2000,
  • 3:22 - 3:25
    right. That is Nickelback back there. I was
    listening
  • 3:25 - 3:27
    to a lot of Nickelback back then. So you
  • 3:27 - 3:30
    can think where I, where I was, right. So,
  • 3:30 - 3:33
    it's 2000. I moved on from ASP. I went
  • 3:33 - 3:36
    into the world of Java. I learned about Spring,
  • 3:36 - 3:39
    about Struts. And that was when someone introduced
    me
  • 3:39 - 3:41
    to the concept of MVC, and I was like
  • 3:41 - 3:45
    oh. Yeah. This is what I needed back there,
  • 3:45 - 3:46
    but it didn't exist there.
  • 3:46 - 3:48
    And, and if you think about it, it was
  • 3:48 - 3:50
    sort of the same concept, right. Like, separate
    your
  • 3:50 - 3:56
    concerns wherever it matters, and, and stop
    reusing code,
  • 3:56 - 3:59
    basically. And after a couple of years of
    doing
  • 3:59 - 4:02
    Java, I was introduced, then, to Rails. I
    was
  • 4:02 - 4:06
    lucky enough to get a job doing Rails programming,
  • 4:06 - 4:07
    and that's what I've been doing for the last
  • 4:07 - 4:11
    seven years. And I've been very happy about
    it.
  • 4:11 - 4:14
    So, if there's someone that has recently moved
    from
  • 4:14 - 4:18
    Java to Rails understand this feeling. So
    I've been
  • 4:18 - 4:23
    happy for the last seven years. Until I hit
  • 4:23 - 4:29
    what I guess I'd call my mid-programmer life
    crisis.
  • 4:29 - 4:32
    This, what happened to me is that I was
  • 4:32 - 4:36
    thinking, that was, that was, those days were
    cool,
  • 4:36 - 4:37
    where you had all these problems that you
    needed
  • 4:37 - 4:40
    to solve with programming and all that stuff.
    And
  • 4:40 - 4:42
    right now I think that everything is just
    there.
  • 4:42 - 4:44
    You just need to bundle install and the, and
  • 4:44 - 4:46
    the world is solved.
  • 4:46 - 4:49
    So I began thinking, programming web applications
    with Rails
  • 4:49 - 4:53
    it's, it's kind of boring. That's, that's,
    that's like,
  • 4:53 - 4:56
    I, I, I hit my mid-programmer life crisis,
    and
  • 4:56 - 4:59
    it's because I began thinking, like, building
    websites with
  • 4:59 - 5:01
    Rails is not enough programming. There's,
    there's a lot
  • 5:01 - 5:04
    of magic like, like Akira just said. Just
    a
  • 5:04 - 5:06
    lot of magic going on. It's, it's not enough
  • 5:06 - 5:09
    programming for me. It feels like, if you
    called
  • 5:09 - 5:12
    yourself a great programmer because you do
    Rails, it's
  • 5:12 - 5:14
    the same thing as calling yourself a carpenter
    because
  • 5:14 - 5:18
    you bought your carpenter at Ikea, right?
    Like. Yeah.
  • 5:18 - 5:20
    I built that, that, that table. Oh, oh you
  • 5:20 - 5:23
    have skills, right? You know what I mean?
  • 5:23 - 5:26
    And, on top of that, on top of that,
  • 5:26 - 5:29
    things like this happened. If you know Konstantin
    Haase,
  • 5:29 - 5:31
    he was ranting the other day because Rails
    is
  • 5:31 - 5:33
    like the worst Rack citizen there is. And
    he
  • 5:33 - 5:35
    was telling, he was telling us that it was
  • 5:35 - 5:39
    because they never contribute features back,
    implemented encrypted sessions
  • 5:39 - 5:42
    in Rails, while it should be on the layer
  • 5:42 - 5:44
    of Rack. You know, things like that.
  • 5:44 - 5:46
    And the problem is that, that we, as Rails
  • 5:46 - 5:49
    programmers, don't want to contribute back.
    It, it occurred
  • 5:49 - 5:51
    to me that it's maybe because most of us
  • 5:51 - 5:54
    don't know what's going on outside of Rails,
    right?
  • 5:54 - 5:57
    Like, if, if you were at that last talk,
  • 5:57 - 5:59
    there's all these concepts that we probably
    don't know
  • 5:59 - 6:02
    where, do, that they belong to Railties or
    to
  • 6:02 - 6:05
    Rack or whatever. We just think that everything
    is
  • 6:05 - 6:06
    Rails, and it's not.
  • 6:06 - 6:07
    And also, well, we used to have all these
  • 6:07 - 6:10
    problems. We used to actually write SQL, you
    know,
  • 6:10 - 6:12
    and now we don't do any of that. So
  • 6:12 - 6:15
    maybe, maybe our mind is not challenged enough.
    So
  • 6:15 - 6:18
    we need to, we need to start thinking about
  • 6:18 - 6:21
    everything that's outside there. We need to
    bring programming
  • 6:21 - 6:25
    back basically, and so that's why I'm here.
    I'm
  • 6:25 - 6:28
    gonna try to show you how to write a
  • 6:28 - 6:32
    web application with Ruby, but not Rails.
    And maybe
  • 6:32 - 6:33
    just a little bit of Rack.
  • 6:33 - 6:36
    You, I'm gonna explain to you a little bit
  • 6:36 - 6:40
    what Rack is. And it's basically just a super
  • 6:40 - 6:45
    cool interface that acts as, yes, an interface
    between
  • 6:45 - 6:48
    web servers and applications. So basically
    what happens is
  • 6:48 - 6:52
    that the web server, whether it is Unicorn,
    Puma,
  • 6:52 - 6:55
    whatever, has to a hash with requests headers,
    right.
  • 6:55 - 6:57
    And that hash is sent over to the web
  • 6:57 - 7:01
    application that, by convention, needs to
    be any object
  • 7:01 - 7:03
    that responds to the call method and receive
    that
  • 7:03 - 7:05
    hash.
  • 7:05 - 7:07
    And then the web application does its thing,
    you
  • 7:07 - 7:09
    know, and the only thing that it needs to
  • 7:09 - 7:12
    do is return back an array with three elements.
  • 7:12 - 7:15
    One should be the http_code of the response,
    that's
  • 7:15 - 7:19
    an integer. The, a hash with all the headers
  • 7:19 - 7:22
    of the response, and a body, which will be
  • 7:22 - 7:26
    any object that can respond to the method
    each.
  • 7:26 - 7:28
    And that array travels back through the web
    server,
  • 7:28 - 7:30
    and then the web server just turns it into
  • 7:30 - 7:36
    something that the browser can understand.
    So, like I
  • 7:36 - 7:39
    said, like you've heard, all you need to run
  • 7:39 - 7:42
    a Rack application is the file config dot
    ru.
  • 7:42 - 7:47
    And define on that file, using the run directive,
  • 7:47 - 7:51
    the object that will respond to call, and
    that
  • 7:51 - 7:54
    will receive that hash of, of headers.
  • 7:54 - 7:58
    So, what you're seeing right here is basically
    the
  • 7:58 - 8:03
    smallest but most useless web application
    ever. But it's
  • 8:03 - 8:07
    just those three lines and that works. So,
    this
  • 8:07 - 8:08
    is the dangerous part. This is where I do
  • 8:08 - 8:12
    some live coding. Call me a rebel if you'd
  • 8:12 - 8:12
    like.
  • 8:12 - 8:16
    So, let's, let's do some live coding. I'm
    gonna
  • 8:16 - 8:23
    get out this here. And let's begin with that,
  • 8:23 - 8:25
    you can see that, right? Yeah. That's good.
    Let's
  • 8:25 - 8:28
    begin with that config dot ru thing that we
  • 8:28 - 8:32
    mentioned there. We need the run directive
    - we'll
  • 8:32 - 8:39
    create a proc, because a proc can respond
    to,
  • 8:39 - 8:44
    to call. We'll ask it to print that hash,
  • 8:44 - 8:46
    you know, that we get, that we'll get from
  • 8:46 - 8:50
    the server, and then just answer 200, a hash,
  • 8:50 - 8:55
    and just some empty array, which is an object
  • 8:55 - 8:57
    that responds to each, right. An array can
    do
  • 8:57 - 8:58
    that.
  • 8:58 - 9:02
    So, let's see what happens. To start any Rack
  • 9:02 - 9:04
    application, all you need to do is run the
  • 9:04 - 9:06
    rackup command, whatever, to reset that config
    dot ru
  • 9:06 - 9:10
    file. And then it just boots up basically.
    So
  • 9:10 - 9:13
    it's telling me that it's booting up on port
  • 9:13 - 9:16
    9292. So if you go to a browser and
  • 9:16 - 9:18
    we reload, there's nothing here because we're
    not doing
  • 9:18 - 9:22
    anything. But you can see here that we get
  • 9:22 - 9:24
    that hash, right.
  • 9:24 - 9:25
    This is, this is what the browser sent over
  • 9:25 - 9:29
    to the, to the Rack application, and it got,
  • 9:29 - 9:31
    well, all that information that the browser
    is sending.
  • 9:31 - 9:36
    So, that is great.
  • 9:36 - 9:41
    Next thing, let's actually do something with
    this. So,
  • 9:41 - 9:46
    we're gonna create a body like, like all web
  • 9:46 - 9:51
    application have, and some, well. It will
    be body.
  • 9:51 - 9:53
    I'm not very good at html so please forgive
  • 9:53 - 9:58
    me. Let's do Hello World. We'll be, close
    the
  • 9:58 - 10:04
    body tag, close the html one. And well. Let's
  • 10:04 - 10:11
    just send that body back. See what happens.
    We
  • 10:11 - 10:15
    restart our web server. And boom. We have
    a
  • 10:15 - 10:18
    working web application that serves us a single
    page,
  • 10:18 - 10:19
    basically.
  • 10:19 - 10:23
    All right. Things are working. The problem
    right now
  • 10:23 - 10:25
    with our web application is that it's only
    serving
  • 10:25 - 10:28
    one page, no matter what the path is. So
  • 10:28 - 10:31
    if you go, like, to, slash, like the root
  • 10:31 - 10:33
    path, it's Hello World. If you go to slash
  • 10:33 - 10:38
    admin, Hello World. it doesn't matter where
    you go.
  • 10:38 - 10:40
    It's always, you know, the same thing. Because
    we
  • 10:40 - 10:44
    need something to actually grab the request
    path and
  • 10:44 - 10:46
    send it over to whatever it needs to be,
  • 10:46 - 10:48
    wherever it needs to go.
  • 10:48 - 10:52
    So, we're gonna use. That's, that's what's
    called a
  • 10:52 - 10:54
    router, usually in the MVC pattern. And the
    router
  • 10:54 - 10:58
    just does, does that. It basically just takes
    the,
  • 10:58 - 11:01
    the request path, and then send it over to
  • 11:01 - 11:05
    whoever needs to handle that request. Specifically,
    this is
  • 11:05 - 11:10
    very complicated logic, in general. It's way
    beyond just
  • 11:10 - 11:13
    doing a case structure. But we'll do that
    for
  • 11:13 - 11:14
    now.
  • 11:14 - 11:16
    If you want to learn more about the router
  • 11:16 - 11:20
    in Rails, it's a gem called Journey. And as
  • 11:20 - 11:22
    you can see, it has features and problems,
    which
  • 11:22 - 11:25
    is basically just designed for Rails and that
    it's
  • 11:25 - 11:28
    too complex right now. And you can imagine
    why.
  • 11:28 - 11:31
    Like, if you, if you define routes, there's
    all
  • 11:31 - 11:34
    these cases that need to be handled. Whatever
    you
  • 11:34 - 11:38
    have. If it, the method, and if you have
  • 11:38 - 11:41
    variables and all that, so it's, it's complex
    logic,
  • 11:41 - 11:44
    right. So we're not getting into that. We're
    just
  • 11:44 - 11:48
    gonna use the same technology that I used
    ten
  • 11:48 - 11:54
    years ago, which is define our case, yay.
  • 11:54 - 11:58
    So, first thing we want to do is say
  • 11:58 - 12:05
    something like path equals env. We're gonna
    get it
  • 12:06 - 12:10
    from those setters. And then say case path,
    and
  • 12:10 - 12:14
    you know, when that path is the root path,
  • 12:14 - 12:18
    just serve this. And if it's something else,
    just
  • 12:18 - 12:24
    say hey, not found. And return a 404, the
  • 12:24 - 12:29
    headers and return that body. And that's it.
    Yes.
  • 12:29 - 12:31
    That's our router. Sweet.
  • 12:31 - 12:38
    So. We restart our application and see what
    happens.
  • 12:38 - 12:43
    So, now product not found. And if you go
  • 12:43 - 12:46
    to root path, Hello World. Great. So, as you
  • 12:46 - 12:48
    can see, the server is getting the same. You
  • 12:48 - 12:51
    know, it's sending the right codes. 404. 200.
    And,
  • 12:51 - 12:55
    and so on. So, we now have some sort
  • 12:55 - 12:57
    of router, right.
  • 12:57 - 13:01
    So, what's next? If we, we probably don't
    want
  • 13:01 - 13:05
    to have this code, you know, just pasted in,
  • 13:05 - 13:07
    in our whole, in a single file and do
  • 13:07 - 13:10
    our whole web application here. So let's move
    this
  • 13:10 - 13:14
    to a class. To, to make it a little
  • 13:14 - 13:19
    bit more understandable. So I'm gonna steal
    this, and
  • 13:19 - 13:23
    I'm gonna put it into a app.rb file. OK.
  • 13:23 - 13:30
    Instead of this, I'm gonna say, like, class
    App.
  • 13:30 - 13:33
    It has to be, it has to respond to,
  • 13:33 - 13:39
    to call method and receive env, or that hash.
  • 13:39 - 13:41
    And I'm gonna end the method. I'm gonna end
  • 13:41 - 13:46
    that. And ident it. And that's it. Now we
  • 13:46 - 13:50
    have to include that to config dot ru.
  • 13:50 - 13:57
    I'm gonna require that file. And then I'm
    gonna
  • 13:59 - 14:03
    tell Rack instead of, of doing stuff here,
    just,
  • 14:03 - 14:06
    you know, send the hash to that, to that
  • 14:06 - 14:09
    class, right. Because now it's an object that
    can
  • 14:09 - 14:12
    respond to each. Sorry. To call.
  • 14:12 - 14:14
    So this. Let's just make sure that this is
  • 14:14 - 14:16
    working well. I don't want to write a test
  • 14:16 - 14:20
    for this because, you saw the keynote. So,
    there
  • 14:20 - 14:24
    you go. It's still working. We have now abstracted
  • 14:24 - 14:28
    our code to, to, to a class. So that's
  • 14:28 - 14:32
    great. What's next? So, I guess what's next
    is
  • 14:32 - 14:39
    to go to our, here, and create controllers,
    right.
  • 14:39 - 14:43
    Instead of having this laying around. We probably
    want
  • 14:43 - 14:46
    a class that says, that does this.
  • 14:46 - 14:51
    So let's create a folder real quick that's
    controllers.
  • 14:51 - 14:58
    We'll put them there. And I'll say, let's
    say
  • 15:00 - 15:07
    root_controller.rb. What? I know what's gonna.
    Hold on. Yeah.
  • 15:09 - 15:16
    root_controller.rb. We say OK. RootController.
    And have, I don't
  • 15:16 - 15:19
    know, the action show. This is where code
    will
  • 15:19 - 15:24
    be.
  • 15:24 - 15:29
    We probably want to have this controller class
    receive
  • 15:29 - 15:36
    that env through the initializer. And then
    say, self.env
  • 15:38 - 15:45
    equals env. We added , let's see. And there
  • 15:48 - 15:48
    you go.
  • 15:48 - 15:50
    And here, instead of doing this, we'll just
    say
  • 15:50 - 15:57
    RootControll.new, get env and show. We want
    to require
  • 16:01 - 16:08
    that controller here. And let's make sure
    this works.
  • 16:09 - 16:16
    It doesn't. Perks of live coding. I know what
  • 16:17 - 16:23
    it is. Don't worry. OK. K. So. We start
  • 16:23 - 16:26
    our web application and it's still working,
    which is
  • 16:26 - 16:28
    perfect.
  • 16:28 - 16:30
    So what else, what else does a web application
  • 16:30 - 16:36
    need? It needs views, right. We need views.
    We
  • 16:36 - 16:39
    need to set our html logic. We need to
  • 16:39 - 16:41
    set it apart and put it in a different
  • 16:41 - 16:46
    component. And, that's like the controller
    html pasted into
  • 16:46 - 16:50
    a controller. So let's create views. Hope
    you guys
  • 16:50 - 16:54
    like haml. I do. So, we're gonna use that
  • 16:54 - 16:57
    to create our views. First of all, we're gonna,
  • 16:57 - 17:01
    we, we need to create a folder. Views for
  • 17:01 - 17:05
    this controller in specific. All right.
  • 17:05 - 17:12
    So, let's create our views. Show.html.haml.
    We need, like,
  • 17:13 - 17:20
    head. Title, Railsconf. We'll create a body.
    And h1.
  • 17:24 - 17:28
    Something like that.
  • 17:28 - 17:34
    Controllers, root_controller, and then here.
    Let's create a method
  • 17:34 - 17:38
    that will be render. And that method, I want
  • 17:38 - 17:41
    it to receive like the, the, the template
    path.
  • 17:41 - 17:44
    And what you need to do to, to render
  • 17:44 - 17:46
    like a template with haml and stuff, you need
  • 17:46 - 17:52
    to open the file first and read it. You
  • 17:52 - 17:56
    need to add some sort of variable, which we
  • 17:56 - 18:03
    call template, and then just say, Dear Haml::Engine,
    can
  • 18:04 - 18:06
    you please render this?
  • 18:06 - 18:11
    See, it's easy. That's why I chose haml. So
  • 18:11 - 18:13
    we don't need this anymore, because our superview's
    gonna
  • 18:13 - 18:20
    do it, and we're gonna say render('views/root/show.html.haml').
    And I
  • 18:25 - 18:29
    think that's it. We probably just need to
    require
  • 18:29 - 18:36
    haml. We don't want it to blow up. There
  • 18:36 - 18:37
    you go.
  • 18:37 - 18:43
    And, let's see what happens. Yay. We're still
    there.
  • 18:43 - 18:46
    So now we have views. The title changed because
  • 18:46 - 18:47
    on that other version, we didn't have. But
    now
  • 18:47 - 18:49
    we do.
  • 18:49 - 18:52
    And, the whole point of what we're doing right
  • 18:52 - 18:55
    now, it's because we didn't want to sort of
  • 18:55 - 18:57
    duplicate code and copy and paste, and so
    we
  • 18:57 - 19:00
    probably need layouts, right? Like, like,
    like with Rails.
  • 19:00 - 19:06
    So, let's create a layout. First thing we
    do,
  • 19:06 - 19:13
    views/layouts. Yeah. That'll work. And let's
    open what we
  • 19:13 - 19:17
    have right now. And just steal the first four
  • 19:17 - 19:21
    lines. No, actually, we need everything, all
    the way
  • 19:21 - 19:22
    here. Yeah.
  • 19:22 - 19:27
    And we indent it. Let's open views/layouts,
    let's call
  • 19:27 - 19:34
    it app.html.haml. Views/layouts/app.html.haml.
    And here's where we paste it.
  • 19:38 - 19:40
    And, like good old Rails, we're gonna do a
  • 19:40 - 19:43
    yield, and there's where we want the view
    code
  • 19:43 - 19:49
    to show up. I'm on time. That's good.
  • 19:49 - 19:53
    We go back to our RootController, and now
    we
  • 19:53 - 20:00
    define a method that will be render_with_layout.
    Same thing.
  • 20:00 - 20:04
    We need to know the template path. And let's
  • 20:04 - 20:08
    see, first we open our layout file. We're
    gonna
  • 20:08 - 20:14
    hard code it because that's how we do. Layouts.
  • 20:14 - 20:21
    No magic here. Read.
  • 20:25 - 20:28
    And do the same thing. Dear Haml::Engine,
    can you
  • 20:28 - 20:34
    please render that layout? The trick here
    is that
  • 20:34 - 20:36
    you can pass a block to render, and then
  • 20:36 - 20:40
    whatever you render inside of the block, that's
    what
  • 20:40 - 20:43
    gets rendered to yield. So we simply call
    render
  • 20:43 - 20:46
    again with that template path that we were
    looking
  • 20:46 - 20:48
    for up there.
  • 20:48 - 20:55
    So, now we change this code to render_with_layout.
    We
  • 20:58 - 21:03
    restart our application. And it's still working.
    So. Now,
  • 21:03 - 21:10
    if I go and change the title, for example,
  • 21:11 - 21:15
    to 2014, then it should, should change. Yay!
    So,
  • 21:15 - 21:19
    now we have a layout. That's great. And so,
  • 21:19 - 21:23
    what else do we need from web applications?
  • 21:23 - 21:28
    So, we usually need to have dynamic information
    on,
  • 21:28 - 21:31
    on our web application. Something like this.
    Like, maybe
  • 21:31 - 21:34
    the name comes from the database, or comes
    from
  • 21:34 - 21:37
    a query param or whatever. So we need to
  • 21:37 - 21:41
    be able to change data on the views, right.
  • 21:41 - 21:44
    So, let's see if, first of all, we just
  • 21:44 - 21:48
    add that variable there, like, like Rails,
    as if
  • 21:48 - 21:50
    Rails will do it. But we can see that
  • 21:50 - 21:53
    it's not that easy. It, it doesn't happen
    magically.
  • 21:53 - 21:56
    So, what we need to do for this to
  • 21:56 - 22:00
    work is we go back to our controller and,
  • 22:00 - 22:03
    well, first of all, we need to define it,
  • 22:03 - 22:04
    right.
  • 22:04 - 22:08
    Let's say, world.
  • 22:08 - 22:12
    And second of all, the render method can receive,
  • 22:12 - 22:16
    as parameter to context of where the layout
    is
  • 22:16 - 22:20
    going to be sort of processed. So basically
    we
  • 22:20 - 22:22
    just need to tell it the context should be
  • 22:22 - 22:26
    the same object. And, and that way this instance
  • 22:26 - 22:30
    variable will be part of the package. So what
  • 22:30 - 22:35
    we do here is we are going to as-
  • 22:35 - 22:38
    to add the context to our render method. But
  • 22:38 - 22:40
    as default we'll just say hey, just graft
    self
  • 22:40 - 22:47
    if there's nothing there. Same here. And we
    need
  • 22:47 - 22:54
    to pass that context to this render method.
    Over
  • 22:58 - 23:02
    here and over here. So it's all the same.
  • 23:02 - 23:05
    And this is gonna happen sort of magically
    because
  • 23:05 - 23:08
    of that default, where we set it to self.
  • 23:08 - 23:10
    And yay. It's working.
  • 23:10 - 23:14
    So now we can populate that variable or, couple
  • 23:14 - 23:17
    of variables with whatever we want basically.
    The most
  • 23:17 - 23:21
    typical thing that we could do would be to
  • 23:21 - 23:24
    send it over in a, in, in, in, like
  • 23:24 - 23:28
    params. Like something like this. If it comes
    as
  • 23:28 - 23:34
    a parameter, do something, or else just do
    world,
  • 23:34 - 23:37
    right. But params is a method that we need
  • 23:37 - 23:44
    to basically define. So let's define that.
    Params. I'm
  • 23:45 - 23:48
    not going to write code to like go to
  • 23:48 - 23:53
    a query string. We're just gonna use a method
  • 23:53 - 23:57
    that already exists in Rack::Utils which basically
    does that
  • 23:57 - 24:02
    - parse_nested_query. What it's gonna do,
    it's gonna take
  • 24:02 - 24:07
    the query string and it's gonna turn it into
  • 24:07 - 24:09
    a nice hash that we can access. So we're
  • 24:09 - 24:13
    gonna add that here in params name and it
  • 24:13 - 24:17
    should work at, at the first attempt. Let's
    try
  • 24:17 - 24:18
    it.
  • 24:18 - 24:22
    So, default is Hello, World. It will say name,
  • 24:22 - 24:29
    I don't know, RailsConf, and it works. Hello
    Jane
  • 24:29 - 24:32
    or whatever it is, you know. It just works.
  • 24:32 - 24:35
    And, well, I guess the last thing that we
  • 24:35 - 24:37
    could do for a web application will be to
  • 24:37 - 24:43
    properly abstract it. And we probably want
    to grab
  • 24:43 - 24:45
    all this code and set it on a controller
  • 24:45 - 24:52
    class, right. Because. Over there. And, OK.
    Now, let's
  • 24:54 - 24:58
    go back to our root_controller and just say
    hey,
  • 24:58 - 25:02
    just inherit from controller. And that's it.
    That way
  • 25:02 - 25:05
    we can, in the end, we can add more,
  • 25:05 - 25:09
    more and more controllers to our super web
    application.
  • 25:09 - 25:11
    The only thing we need to do is require
  • 25:11 - 25:18
    controller. Here, and. Let's make sure that
    it still
  • 25:18 - 25:18
    works.
  • 25:18 - 25:23
    It still does. That's good. That's always
    good. Yup.
  • 25:23 - 25:27
    There you go. So that's it on the coding
  • 25:27 - 25:29
    side. As you can see, you have a working,
  • 25:29 - 25:34
    perfectly working web application right there
    from using no
  • 25:34 - 25:41
    frameworks at all, only your Ruby code. Now,
    I
  • 25:41 - 25:44
    probably don't have the time to add models
    and
  • 25:44 - 25:48
    all that because that's different logic, but.
    You could
  • 25:48 - 25:51
    just, you know, inherit ActiveRecord::Base,
    they, they, you know,
  • 25:51 - 25:54
    they've already done it. And it's, it's hard
    logic
  • 25:54 - 25:55
    you don't need to redo. All you need to
  • 25:55 - 25:58
    do is just, you know, define classes and say,
  • 25:58 - 26:00
    inherit from ActiveRecord::Base, and you will
    get, like, all
  • 26:00 - 26:02
    the magic that you get on Rails.
  • 26:02 - 26:04
    If you're a little bit more hardcore, then
    you
  • 26:04 - 26:07
    can use sequel, and just write your methods
    like
  • 26:07 - 26:09
    so, and you can get access to the database
  • 26:09 - 26:12
    that's, as if it was a hash, and just
  • 26:12 - 26:14
    write your dot all, your dot find, all that
  • 26:14 - 26:17
    logic. And if you're even more hardcore, you
    can
  • 26:17 - 26:21
    directly use the pg gem or the mysql gem,
  • 26:21 - 26:24
    and just, you know, do this sort of crazy
  • 26:24 - 26:28
    stuff where you actually write SQL. Yay SQL.
    And
  • 26:28 - 26:31
    then just, you know, iterate through the results
    and
  • 26:31 - 26:33
    put them in the hash and all that. This
  • 26:33 - 26:35
    is, this is fun. Like, this is programming,
    right.
  • 26:35 - 26:40
    And one last piece of advice I have for
  • 26:40 - 26:46
    you is don't ever actually do this. Don't
    ever
  • 26:46 - 26:49
    actually do this unless you're some sort of
    speed
  • 26:49 - 26:52
    freak or performance freak. When I run my
    tests,
  • 26:52 - 26:56
    my super web application was able to handle
    700
  • 26:56 - 26:59
    requests per second, and every request will
    take one
  • 26:59 - 27:03
    millisecond, which is pretty fast, right.
    But when I
  • 27:03 - 27:06
    created the same application using Rails,
    I had like
  • 27:06 - 27:12
    2x slowness, right, right. It will take two
    milliseconds
  • 27:12 - 27:14
    to, to run, which is unacceptable. I want
    one
  • 27:14 - 27:18
    milliseconds. But this is unfair because Rails
    solves all
  • 27:18 - 27:22
    these problems, right. We have logging, caching,
    database pooling,
  • 27:22 - 27:24
    sessions, cookies, security, all of that,
    that we're not
  • 27:24 - 27:28
    considering on our own application.
  • 27:28 - 27:29
    But even if you don't want to do this
  • 27:29 - 27:31
    in real life, you do want to read code,
  • 27:31 - 27:33
    and you do want to go and, and, and
  • 27:33 - 27:37
    try and see how Rails is doing things. You
  • 27:37 - 27:40
    want to try to understand, how is it doing
  • 27:40 - 27:44
    it? Like, right, you want to do find that
  • 27:44 - 27:46
    code that connects to the database, that code
    that
  • 27:46 - 27:50
    turns dot find into select star from that
    table,
  • 27:50 - 27:52
    you know, all that, you want to go and
  • 27:52 - 27:54
    read and try to understand how things work.
    And
  • 27:54 - 27:58
    then once you understand, try to write your
    own
  • 27:58 - 28:02
    framework. Well, why not? There's, there's
    space for, for
  • 28:02 - 28:04
    a new framework. Maybe, maybe you'll be the
    next
  • 28:04 - 28:09
    DHH and will, and will be able to afford
  • 28:09 - 28:11
    and race car and all that.
  • 28:11 - 28:13
    But the most important thing is that you will
  • 28:13 - 28:17
    understand, like, master this topic. You will
    know, you,
  • 28:17 - 28:19
    you will have that feeling of saying, hey,
    I
  • 28:19 - 28:21
    know how this works. This is great, now I
  • 28:21 - 28:27
    can go back to doing my Ikea software. But
  • 28:27 - 28:31
    I at least I know how it works, right.
  • 28:31 - 28:33
    And then if you see the Rails core team,
  • 28:33 - 28:35
    give them a hug. Because you will understand
    also,
  • 28:35 - 28:37
    like, the pain that they had to go through
  • 28:37 - 28:41
    to get Rails to where it is right now,
  • 28:41 - 28:42
    because it's not easy, right. We just, we
    just
  • 28:42 - 28:45
    wrote like thirty minutes of code, but it
    does
  • 28:45 - 28:47
    basically nothing. It needs to take care of
    routing,
  • 28:47 - 28:51
    like I said, caching, security, and all that.
    And
  • 28:51 - 28:53
    that's, you know, a lot of lines of code
  • 28:53 - 28:56
    that need to, that need to happen. So, so
  • 28:56 - 28:58
    you see a Rails core guy, you say, hey,
  • 28:58 - 29:01
    thanks for that. Give him a hug. And my
  • 29:01 - 29:03
    last disclaimer is that I do not actually
    think
  • 29:03 - 29:06
    that writing web applications with Rails is
    boring. That
  • 29:06 - 29:08
    was just added for drama.
  • 29:08 - 29:12
    And I hope you understand that. That's it.
    I
  • 29:12 - 29:15
    will Tweet or, whenever you see the slides
    you
  • 29:15 - 29:17
    will see like the code example on, on my
  • 29:17 - 29:20
    talk on that, on that url. And thank you.
Title:
RailsConf 2014 - Web Applications with Ruby (not Rails) by David Padilla
Description:

more » « less
Duration:
29:49

English subtitles

Revisions