

It's about time to start fighting against the Rails “magic” myth - rohitarondekar
http://blog.plataformatec.com.br/2010/12/crafting-rails-applications-why-i-wrote-this-book/

======
j4mie
I think you might be fighting an uphill battle here.

Some developers prefer Python, some prefer Ruby. An individual developer might
be able to reel off a list of reasons why one is better than the other, but in
the end it comes down to something intangible and subjective - "Ruby just
_feels_ better" or "Python _fits my brain_ better".

The concept of "magic" is very similar. What feels magical and opaque to one
developer might be plain and obvious to another. When you ask what "magic"
means, you'll get different answers from different people.

From my point of view (as a Python/Django developer), even the basic
_commands_ that Rails uses feel strange. Compare the very first line of code
that you run in a Django project vs a Rails project:

    
    
        django-admin.py startproject mysite
    

with

    
    
        rails new blog  
    

The former says: "run the Python script called django-admin.py" (which
immediately tells me that this is just a Python script that I could read, if I
were so inclined) and pass the arguments "startproject" (which is a clear
description of what is about to happen) and "mysite" (which is, fairly
obviously, the name of the project to start). This reads like a sentence of
the form 'use <tool> to perform <action> with arguments <arguments>'.

The latter says: "run the command rails" (what is this? A Ruby script? A bash
script? A binary? Why is it called "rails" when the whole framework is called
"Rails"?) and pass the arguments "new blog" (obviously this is creating
_something_ , but what? In most languages, "new" is a keyword that is usually
used to create instances of classes - so is it creating an instance of
something called "blog"? Does that mean that Rails knows what a "blog" is
already?) To me - this is magic. Rails says "type this incantation and I'll do
some stuff for you". Django says "here are some tools you can use to do
stuff".

You might disagree with me entirely in this particular case - perhaps you find
the Rails example clearer - which is fine. The point of this example is to say
that framework and language preference is so intangible that the _very first
line_ of your documentation can sway someone's opinion either way. Instead of
fighting against the "magic myth", you should just be trying to attract
developers who _like_ your particular brand of magic (or, alternatively, don't
see your code as magic at all).

~~~
cmelbye
django-admin.py and "rails" are the exact same thing, it's just that the Rails
command line utility doesn't have an unnecessary Ruby extension. I'm not sure
why "new" is a magic incantation while "startproject" is an intuitive command
line option just because you're not familiar with the command line arguments
for "rails".

~~~
count
You're repeating exactly what he said :)

------
aaronblohowiak
Convention over configuration: sane default values.

magic: changing the scope in which a block is eval'd so you can inject
BlankSlates that have method_missing defined on them that then do some string
manipulation in order to pick which code path to take.

Sometimes you need to lean pretty hard on the super-dynamic features to get
the api you want. But is it worth it?

~~~
JonnieCache
is this the routing DSL you're referring to here? The activerecord query
building stuff is much simpler than this, i know that.

If anyone wants to get a head start in understanding the magic, Ryan Bates has
done excellent walkthroughs of the routing DSL and the activerecord query
building method chaining source code:

[http://railscasts.com/episodes?utf8=%E2%9C%93&search=wal...](http://railscasts.com/episodes?utf8=%E2%9C%93&search=walkthrough)

edit: to add to the list of stuff that rails does which is 'magical,' I still
get uncomfortable over the way that instance variables I set in the controller
scope are 'copied' to the view scope. This is obviously a necessary evil
though.

The real cost of rails' magic is the rampant and wanton Demeter Violation,
which can make testing very difficult in some circumstances.

<http://en.wikipedia.org/wiki/Law_of_Demeter>

~~~
alextgordon
"Ugh, I made this routing library, but the API is such a hack."

"What about calling it a 'DSL' rather than an API? Then nobody will be able to
claim you're abusing Ruby, because it's an entirely new language!"

"I doubt anyone would ever buy that..."

~~~
JonnieCache
Its called a DSL because it is extremely declarative, and because while it is
obviously a subset of ruby syntax, it does not have to look like common ruby
at all.

I take your point though, I do get that feeling sometimes. There is a lot of
showing off by ruby API developers.

I think there comes a time in every ruby hackers life when they get the urge
to write an API that makes use of every single
metaprogramming/reflection/self-modification feature in the language, because
it looks like so much fun. We spend our work days writing rails with all its
fancypants DSL-like bits, and we think "I want to do one of them!"

Mine is a DSL for defining regular expressions in natural language, and my god
does it abuse metaprogramming. All the methods are defined at runtime by
iterating over datastructures that list the regex spec. instance_eval(&block)
all over the place. It is fucking brilliant. And not finished. Obviously.

------
martingordon
A lot of the apparent magic comes from the fact that most Rails developers
never take the time to properly learn Ruby.

------
kondro
It's definitely nice to get a resource like this, but anyone who spends a
reasonable amount of time writing applications for Rails should pick up all
this. There really isn't that much Magic, it's convention.

Think of it like Struts, Spring or the Zend framework with all the
configuration done for you with excellent documentation.

~~~
bad_user
I think both the author and you are missing the point.

Ignoring the people that just reiterate poorly formulated ideas heard
somewhere else, the complaints about magic were quite valid: originally the
Rails source-code was too hard to read and comprehend.

When I used Django, I read most of the source-code from django.core and even
stuff from django.contrib.

Django also has its quirks. I could understand pretty easily how a ForeignKey
works (I don't know, it just clicked), but understanding how a FileField works
was hard because the object I was receiving was just a proxy that forwarded
all messages to an object that I couldn't figure out how it got instantiated
(or the logic behind the decision). And when I did figure out how the thing
worked, I puked a little and came up with an inelegant hack for what I was
trying to do.

Figuring out how stuff works is really useful when you want to extend the
provided functionality or work around a bug that has to be fixed RIGHT NOW or
break free of those conventions that sometimes are just too limiting. Not to
mention incomplete documentation which many times is seriously lacking.

Django's source code (when compared to Rails), while also full of conventions,
has this neat property that I like: you can read and understand 70% of its
source-code (going line-by-line with a debugger) without fully understanding
Python's meta-programming capabilities, which makes it really friendly to
beginners.

I mean, the convention for "has_many :tags" is really neat, but such
conventions have to have complementaries in the Rails source-code ... i.e.
clear conventions for how to find and read the source-code of this mechanism.

Fortunately Rails 3 got a major refactoring effort, that I could read portions
of it. It's more modular and reader-friendly now: and this is partly because
people complained about magic. With a couple of additions here and there, it
can be the web framework I've been waiting my whole web-dev carrier :-)

~~~
josevalim
I agree with you. I had the post a bit longer but I cut it down a bit before
publishing and it discussed some points you mentioned.

People had reasons to call Rails as something "magic" some time ago. But
"magic" at that time really translated to poor design and lack of
documentation.

Most of Rails has changed since then. Rails has good documentation for already
some time, the internals are cleaner than ever before and should continue
improving (for example, check Aaron Patterson's work on Active Record for
Rails 3.1). But people still call it magic, because it became an habit.

Even simpler and smaller things in Rails, like the "find_by_email" method in
Active Record that relies on Ruby's method_missing, were for a long time
called as "magic finders".

Another proof of that habit was my take on Inherited Resources. The code is
clean, modular, well-tested since day one, but I still stamped "magic" on the
README when I first released it because it sounded cool. This is the mistake I
want to prevent people from doing it all over again.

Maybe a better moto would be: "There is not such thing as magic, only bad and
poorly-documented code."

------
tyrmored
New PHP developer here. Just some perspective from an "industry" guy rather
than a super-smart startup guy. I can clearly remember my first foray into
Rails, and it'll be a while before I try it again unless I need it for a job.
I just don't like it, and here's why.

For people like me, Rails is at least at first glance very unsettling. I
followed the tutorial on their site about making a guestbook, on which they
proudly boast how fast you'll have it up and running. So I punched in the code
they suggested and bang, guestbook. They certainly weren't lying (maybe
exaggerating a tad) about the speed, but ...

Wait. What the fuck? You've made a _lot_ of assumptions about how I wanted
this to work. What say I didn't want the form to look like that? Why are you
writing CSS for me? That's _my_ job! Going further into it made me feel even
more uncomfortable, and after seeing the ORM database abstraction and taking
my beloved SQL away from me, I left Rails behind.

It's one thing to provide a clever wrapper method to efficiently sort integers
in PHP or Ruby without having to import or implement quicksort or whatever.
That's abstraction me and my self-taught ilk are comfortable with. But the way
Rails assumes what you meant from your code is just distressing. You don't
feel like you wrote it, and this code is running and producing a finished
webpage without you needing to understand how it works. You could reasonably
respond that this is just another layer of abstraction, but producing an
entire webpage for you based on some very cursory instruction does not have
the same "pure" feel that a sort() implementation does.

My friends think it's great. I think it's scary. And reading some other elated
posts from Rails nuts around the web about the whole "just works" thing and
the magic going on really _is_ unsettling. You're not building from the bottom
up -- schema -> logic -> markup -> style -> scripts. It's all coming together
in one big vaguely uncomfortable clump, and _you didn't write it_. Anything
more than a vim macro/TextMate snippet or two that generates code for me --
even if I can edit it afterwards -- gives me a cold shiver, and makes me feel
like I'm using Dreamweaver again.

You could read the code to see what it's doing and tweak accordingly, but
then, why not write the code yourself in the first place?

------
richbradshaw
I've tried Rails a couple of times, but have never persisted with it as I
can't work out how to do anything other than the default stuff. I make
scaffolding, which is great, but then I want to take the scaffolding, use it
as a starting point and change it. But the scaffolding doesn't seem to exist
anywhere - it's just magically in existence.

I want to add authentication - every tutorial recommends different packages to
use, but I don't want som prewritten code, I want to set a session cookie, I
want to read it, I want to add stuff to databases manually, I don't want some
random code providing this without understanding what's going on!

I'm sure that it's an easy thing to work out, but every time I get fed up with
not knowing where anything is coming from so I give up and go back to what I
know.

~~~
jeremymcanally
> it's just magically in existence

You must not have tried Rails past say 1.2 or so (I can't remember when they
took that out). Scaffolding has been generated for some time, which means the
code is just spit into the app/ directory. You can go in and change whatever
you want with it.

As for the rest of your complaint, then perhaps something as abstract as Rails
isn't really for you (Sinatra maybe?). Though really, why do you want to do
all that manually? Just read the framework docs, which are quite good now, and
code, understand how they work (really, it's not hard I promise), and use the
abstractions. You'll thank yourself later.

~~~
richbradshaw
These comments have all been really useful – it was a while ago that I used
Rails – seems that things have come a long way since I played. I'll have
another look + at Sinatra. Thanks!

------
geebee
This sounds like a really good book. I'd love to read it, mainly because I am
one of the people frustrated by rails "magic" (which I fully acknowledge comes
from my lack of understanding of the framework).

I think that one of the reasons Rails appears to be magic to _me_ is that I
find it harder to do web programming in rails without the framework than with
it. Hear me out, please, I'm coming from Java...

I can easily hack something together with jdbc, jsp, servlets, sql, pojos, and
so forth. I'm not saying it's a good idea, but I can do it. Maybe this is
because I started with java before all the mvc, orm, DI frameworks were in
place. Maybe if I'd started with mod_ruby on apache prior to encountering
rails, it would be different.

Now, I don't mean that it's easier to create a large, complicated site with
servlets and jdbc instead of spring, hibernate, and so forth. What I do mean,
though, is that if I need to do something in framework-less java, I can do it,
whereas doing it the "spring way" is "harder" - ie., I have to go research how
spring does it, figure it out, and so forth. And if I can't, or if it takes
too long, I can (and do) say fuckit and just hack it all up in java.

In rails, if I don't get it, I'm still incapable of dropping to a lower level
of programming. And that means that if I end up in a bind, I'm really screwed,
because I don't understand the magic. Here's the thing - I really dig Rails,
but eventually something _always_ happens, and then the fact that I don't
really understand how this magic wand I stole from the rails guys actually
works bites me in the ass.

I've carefully avoided ever saying "it's confusing", or "rails can't", because
I'd be wrong. So definitely, I want to read this book.

------
mpk
It's open source.

I played with it a bit and then read the source. Poof! Magic gone.

~~~
theBobMcCormick
Yup. Not only is it Open Source, but there's a plethora of blog posts and
articles just a Google search away that'll explain pretty much every aspect of
how Rails works (seriously.. it's been blogged to death and back).

When people say it's magic, what they're really saying is: "It's unfamiliar to
me, and I'm to lazy to go find out how it works. So rather than just STFU, I'm
gonna complain about too much 'magic'." :-)

~~~
towelrod
You guys are right, no one should ever write a book. About anything, ever.

~~~
theBobMcCormick
Huh? Where do you get that? I think people writing books is awesome, but I
don't recall my comment saying anything about that. I was just commenting on
the people who dismiss Rails as "having too much magic", when what they really
mean is that they're uncomfortable with how different it is from what they're
used to. Now, to be clear, there's nothing wrong with trying a new technology
(Rails, Erlang, Node.js, whatever) and deciding it's not for you. There's also
nothing wrong with _not_ trying a new tech because you're just to damn busy
with something else. :-). What I object to is people who just grab a
"soundbyte" like "too much magic" as an excuse for not forming an honest
opinion about something.

------
vsync
Good documentation definitely helps. However what concerns me more is the
growing tendency of Rails and related packages to do more and more "magic"
without warning the user, at the expense of best practices and the principle
of least astonishment. The best example I can think of offhand is Bundler
"helpfully" invoking sudo to modify your global system settings, as the
default option.

------
mikeocool
I don't think the 'magic' is rails' real problem. It's the fact that all of
the effort that went into making everything happen 'automagically' gets in the
way when you want to do something the core developers never thought of.

~~~
getsat
Can you provide an example? I'm having trouble conceptualising a situation
like this. (Not being snarky)

------
fleitz
No, it isn't. I was talking about this earlier on a topic about java. Magic is
good, it keeps the 'I don't like magic' people away.

It provides a slow introduction to noobs and introduces them to the mindset
that you shouldn't have to do a lot of configuration for things to just work
out of the box.

Remove the magic and pretty soon we'll start having to use factory classes. Or
a web.config file. Or any of the other annoying things you have to configure
to some sane value every time you start a project with any other framework.

~~~
josevalim
Things like convention over configuration must still exist. All the whistles
and surprises that you get when you first come to Rails must still be there.

What the blog post advocates is for giving good explanations, books,
documentation instead of blaming magic as the reason everything works.

