Rails does a ton of stuff, and it has the reputation of including too much magic. I thought the same too! But now, Iām kinda used to this āmagicā, and I donāt find it so overwhelming anymore.
So here are a few things about Rails that might help you get started. This list assumes that you have experience with backend web development using Node.js and Express, but I suspect a lot of the information will be similar if youāre experienced with something like Python and Flask.
Even after many years of using Rails, I still donāt quite know how it initializes controllers or views. But controllers and views have always worked reliably, and I can be productive with the framework without knowing these details.
That said, it is helpful to keep these four in mind:
app/
folder is important since thatās where most of your code will live.config/routes.rb
file is important, but you donāt often need to look at the other files under config/
.db/
folder is important since it keeps track of what the database schema looks like, and since it keeps track of all the changes that was made to your database schema.test/
or spec/
folder, depending on if the codebase youāre working on uses Minitest or RSpec respectively, is pretty important too.bundle
program is like yarn
or npm
Gemfile
is like your package.json
file.Gemfile.lock
file is like your package-lock.json
or yarn.lock
file.bundle exec
is like npx
.Gemfile
. This happens in the file config/application.rb
(specifically the line that includes Bundler.require
). There may be some exceptions though, like if the name of the library is different from what needs to be required.app/
folder. Since each file declares a class or module, each file is accessible from every other file.All that said, if you have to explicitly require
a file that you wrote and have in your app/
folder, you might have put the file in an incorrect place!
Rails likes to follow English rules. These usually just some conventions, and you can often configure title to be different. These conventions let Rails do things by guessing, and without you needing to give it thorough instructions.
For example, ActiveRecord has a few recommendations around naming:
has_many :friends
has_one :friend
belongs_to :friend
So when has_many
is used, Rails knows to singularize the word, turn it from snake_case to CamelCase, and then find that class. Again, thatās just a convention, so you can override it and do it differently.
I do recommend following Railsā conventions, even if it might seem a bit arbitrary. You kinda need to fight Rails to against its conventions.
html_safe
or raw
. It can open you up to XSS attacks.Metaprogramming is a pretty big category, and itās basically code that writes code. It first took me a long time to understand what that meant, but hereās an example in JavaScript
var foo = ["a", "b", "c"];
var obj = {};
foo.forEach(function (letter) {
obj[letter] = function () {
return "You called the function: " + letter + "()";
};
});
obj.a() // => "You called the function: a()"
In the example above, we didnāt define three independent functions a
, b
, and c
. Instead, we wrote some code that defined those functions.
Similarly, Ruby lets you dynamically create methods, classes, modules, and even variables! It can be helpful, but it can also get hard to read. So Iād generally recommend against metaprogramming if you can avoid it!
(But itās also pretty fun, so donāt let me stop you š)
Monkey patching is when you āre-openā some code that you donāt own, then override or add something. Hereās another example in JavaScript:
// In the browser console on https://reactjs.org/
React.hello = function () { return "there" }
React.createElement = function (a, b, c) { return "no YOU createElement" }
React.hello() // "there"
React.createElement('h1', {className: 'greeting'}, 'Hello there') // "no YOU createElement"
Monkey patching is common in Ruby because you can override and extend basically anything. One of Railsā own libraries, ActiveSupport
, is the most well known, and it extends Ruby with lots of convenient features.
I generally would recommend that you avoid writing monkey patch since changes are global. You or your colleagues might run into bugs or unexpected behavior. And you generally donāt have to anyway! Thereās usually a better, safer way than monkey patching.
Ruby does have a relatively unused feature called Refinements, which lets you monkey patch much more safely. There are good resources online if you are curious, including the official documentation.
Models go in app/models
, controllers go in app/controllers
, and etc. But what goes in a model, and what goes in a controller?
app/services
. This way makes sense too, since these plain Ruby objects are small and easy to test, and since it keeps models and controllers relatively smaller too. Again, Iād say this was a critique of the second option.So what is the right way? A lot of it will depend on what your coworkers think. But here are some tips:
app/services
is a pretty safe bet.Thatās kind of it! But I do want to mention one more thing (I wouldnāt necessarily call it a tip).
You can put non-ActiveRecord files in app/models
. I think this is a good choice when youāre writing business logic or external services that you can model as objects. Here are some examples where each returns something like an array of GoogleResult
instances:
GoogleResult.query(term)
GoogleSearcher.call(term)
Google.search(term)
User.search_google(term)
The first option is the most object oriented way, and the middle two are more imperative. There are pros and cons to both kinds of approaches, but Ruby is largely an object oriented language, and I think Rails feels most natural when writing code like the first.
I learned Rails a long time ago, and I learned Ruby even longer ago, so itās hard for me to recommend good resources for learning Rails. That said, I know that I found the Rails Guides very helpful!
Thereās a framework called Sinatra thatās very similar to Express. I wouldnāt necessarily recommend it, but it might be helpful to play with it to get familiarized with the Ruby web ecosystem, but without all of the extra features that Rails comes with.
Remember there isnāt any āmagicā in the Rails codebase. Itās just code that a bunch of wrote and shared with the world. You can open it up, read it, and understand it if you wanted.
Thatās it for now! Hope this helps you start working with Rails.
Thanks to Noorulain for suggesting improvements!