× {{alert.msg}} Never ask again
Receive New Tutorials
GET IT FREE

Ruby on Rails Q&A With Rails Contributor Steve Klabnik

– {{showDate(postTime)}}


This article is based on the Codementor Hour of Code Office Hour hosted by Steve Klabnik, who has made  245 commits to Rails and is well-known in the Rails community for his contribution. The office hour was an open Q&A where the participants could ask Steve anything, and here are some questions participants have asked Steve, including how one should render layouts, separate the front-end and back-end repositories, and more.


How do you render layouts in Rails? Can you have 12 different layouts for 12 pages?

Rails gives you the ability to render whatever layout you want to, so you can choose to share the layout between some or none of the pages. By default there will be one layout that applies to every page, bit it’s a matter of specifying whether or not you want to use a different layout, and it’s not significantly different than using one layout. I’ve noticed that people tend to have 2~3 layouts: a marketing side of the layout, the app part of the layout, and sometimes a third one.

Of course, there’s sort of a conflict here in that there are multiple ways to do one thing. Rails usually picks one, but there are other valid ways of doing things.

Basically, in Rails you have an asset pipeline where you’d want to serve one .js and one .css file for your entire website, and those will get hashed on the first request so you don’t need to keep loading things. The asset pipeline is set up so that all of the individual stylesheets you make will be minified and put into one giant one, and then you use things from there.

There are definitely people who think the asset pipeline is an anti-pattern, and it has always been one of the most controversial things about Rails where people either love it or hate it. Since front-end is my weakest area of programming, I won’t stake my claim on which one is better or which solution is the best. You can change the configuration options in Rails, but personally I just leave it to the default and follow what Rails does.

How do you communicate with a front-end developer?

What I’ve done in the past with various startups and consultancies is I prefer to let the front-end people be in charge. Ultimately, the front-end is what the users see and it’s what matters at the end of the day, so I try to get the front-end developer to tell me what they need from me.

Usually you’d have a branch in Ruby, and both you and the front-end work on the same branch where you’ll push a commit and they’ll pull it down. Rails has a strong convention, so the names of routes are usually pretty obvious and you don’t need to discuss much about what the URLs would look like when you take about the route configurations. However, if you’re going to invent your own convention, you’ll need to talk about what the URLs should be before setting them up.

Most of the times, I’d just sketch out a route that just returns dummy data, and they can work on all their stuff while I work on implementing the route to submit the real JSON. Then we put the two things together and everything works well. Obviously, sometimes you’d have to go through rounds of iteration and vision, but this is why I like a firm distinction between clients and servers. The JSON is where we all meet, so we can just sit around the JSON and talk about what needs to happen.
Inter-team communication is whole other can of worms and we don’t really know how to do this well yet.

What do you think of having an application access multiple databases for different Rails apps? Using an API to help apps communicate across databases is not very efficient.

This is an interesting area that has shaken out in the last couple of years. I will say that letting 2 apps share a database for communications is something that works well when you start, but eventually it will cause problems.

A good way to explain this will be through job queues, and it is why the Rails originally had a delay-job gem that stores your background job in a database and your job runner would read it, find the job, and put the job back in. What ends up happening in this sort of situation is quite similar to having 2 different apps share the same database for communication purposes, and you will introduce a lot of contention on your database. The second both your applications need access to scan the same table, they will have to wait for the other app to be done, and this introduces a lot of IO overhead.

So, what Rails did for the job queue situation is to use other databases just for the job queues. For example, Resque uses Redis. That way, your job stays in Redis and your main code stays in your database and there won’t be any contention.

That said, Rails is kind of bad at accessing multiple databases from a single Rails app—which is not necessarily a bad thing, since if their goal was to do a lot of multi-database things it will paint Rails to a corner.

One approach to solving your problem may not be appropriate until you’re bigger, but it’s to use SOA (service-oriented architecture). I’ve seen people introduce an internal-only service that owns a particular database, and it works well for them. Basically, if your service1 and service2 both need to communicate in some way, they will both talk to internal service3 and that service will handle this sort of information. Rather than having both services directly access the raw database, it is a good pattern to go through a service that can control and monitor this sort of thing.

Let me also add that I’m not a big fan of HTTP in internal-only services. HTTP was designed so it could communicate across organizational boundaries, but it is not a good choice if you’re looking to control both ends of the pipe since you’ll run into scalability problems. I tend to prefer things such as Cap’n Proto, binary, or super low-level protocol for communicating inside a network and building internal APIs. I would never expose Cap’n Proto API to the world, but I wouldn’t use HTPP internally, either—I’d use it for external-facing APIs. Protocols are good at different things.

At any rate, some people go extremely SOA, while others just build one or two services. People do this for refactoring Rails apps too, where they start breaking chunks out of their app when it gets too big. In general, a good way to design software is to name your concepts, since it’s a principle in Object-Oriented Programming. If there is a concept in your system, it should have a name and be its own class. If you have something really important for two applications, it should have its own name and therefore also have its own service, as it’s “the right way” to do things. Of course, there’s always a balance. When you start off, you probably just want to do dirty hacks and get things done, but eventually you realize you have to do things “the right way”. However, if you did things right from the start, you may not even be able to ship your project, so you need to do a lot of balancing and judgment.

Having an application with read-only access to multiple databases is definitely an area where things will be easier, since you don’t have as much traffic you’d otherwise have with the addition of write traffic. So in this case, doing so doesn’t sound as problematic and you need to use judgment at certain points. On the other hand, if you do this you’re definitely going to be writing something that is awkward for Rails, which means it could be better.

One of the things about open source is that the things people do all the time are well-supported, and the things people don’t do all the time get a little sketchy. Perhaps if more people do this there will be more support and improvement in this area.

What is the best way to separate the front-end and back-end into two repositories? Should you use Git submodules, or make a gem, which would be an engine that only contains the models?

I haven’t done this sort of thing before myself, but I’ve talked to people who have made an engine gem that only contains models included in multiple apps, and according to them it has worked well for them.

A more advanced way to do this is to run an internal-only gem server through bundler, as it can run multiple gem servers, and then host your model gems from there. Again, I haven’t done this before, but I’ve heard some large organizations have done so.

Personally, I would take the engine approach. Everyone I’ve heard who used Github’s modules for anything ended up unhappy with it. We’re currently using Git modules for the Rust project, since it’s okay for vendoring things, but historically submodules have always been a really awkward thing, so I try to avoid them if possible.


With over 200 repositories on GitHub, Steve Klabnik is known for his contribution to open source projects, where he has 1900+ contributions in 2014 alone. He is currently ranked #36 on the all-time Rails Contributors list, and has written the guide Rust for Rubyists. As of June 2014, Steve has joined Mozilla to work on the official Rust Documentation.

Steve KlabnikNeed Steve’s help? Book a 1-on-1 session!

View Steve’s Profile or join us as an expert mentor!



Author
Steve Klabnik
Steve Klabnik
Active Ruby on Rails Contributor
I work on many open source projects. I have 273 repositories on GitHub, and am in 15 organizations. Some of them are huge, like Ruby on Rails. Some of them are small, like my own little side...
Hire the Author

Questions about this tutorial?  Get Live 1:1 help from Ruby on Rails experts!
K M Rakibul Islam
K M Rakibul Islam
5.0
★Top Ruby on Rails Mentor since January 2016 (100 months in a row!)★
Experienced (15+ years) developer and friendly Ruby on Rails and React/Next.js/Redux Developer/Mentor (with passion for helping others learn) | ★...
Hire this Expert
Taiwo
Taiwo
5.0
Experienced fullstack developer and co-founder
Thanks for checking out my profile. I have over a decade of full-stack dev experience with languages/frameworks like Ruby, Rails, Javascript,...
Hire this Expert
comments powered by Disqus