

How I Learned Enough Ruby On Rails In 12 Weeks To Launch Freelancify - james-fend
http://www.webstartup.me/learned-ruby-rails-12-weeks-launch-freelancify

======
tptacek
Congrats on the launch. I think I speak for everyone on HN when I say, you're
going about this the right way: learn enough to build applications for
yourself, whether or not you're going to be a code committer over the long
term.

Can I give you some quick advice? Don't take this the wrong way: Rails makes
it easy to learn enough to be dangerous in 12 weeks. Some quick hits on
obvious things you should look over in your application to ensure it isn't
overtly insecure:

* Every model class should have an "attr_accessible" statement, and the attributes you expose through it should be minimal. A very common misconception: "the things in attr_accessible are the only attributes users can set". Not so! The things in attr_accessible are the only attributes users can set _automatically, through mass assignment_. You can expose things that aren't in attr_accessible by manually settings them with assignment statements. Assume anything that's in an "attr_accessible" list, and _every_ attribute of a model without attr_accessible, can and will be set to the most hostile possible value, like "role=admin".

* Rails programming intros have a bad habit of introducing ActiveRecord finders in the context of the model class object --- in other words, "Post.find(params[:id])". This is exactly the wrong way to do it; it's so bad that you can literally generate a list of vulnerabilities on Rails projects by grepping app/controllers for "[A-Z][a-z]+]\\.find". Instead, make sure all your finders work via associations, like "@current_user.posts.find(params[:id])".

* Use a popular plugin for file uploads. Rails doesn't do much of anything to defend against file upload/download vulnerabilities. If I was building a public-facing Rails application, I'd do whatever I could to keep the filesystem namespace out of my requests --- storing all files on Amazon S3 without explicitly storing them in temp files is a good way to do this.

* Don't enable the old-style wildcard route ("/:controller/:action/:id) or any of its variants ("/posts/:action/:id :controller => :posts); whether you declare methods "public" or "private" in a controller should have nothing to do with whether they're exposed to attackers.

* Have a "PreauthController" that inherits from "ApplicationController" and _disables_ the is-logged-in check; in other words, every controller, particularly every controller generated by "rails generate", should be post-authentication _by default_. Set up the before_filter that checks for a valid user session right there in ApplicationController, then "turn it off" for the LoginController by having it inherit from PreauthController. Similarly: if you can get away with not having an AdminController at all --- run a totally separate Rails app for admin that requires a VPN to get to --- do that; otherwise, have an abstract AdminOnlyController class with no methods in it that does nothing but set up a before_filter to check for admin privileges, and have every admin-only controller inherit from it.

* Pretend the backtic operator (the one that executes Unix commands) doesn't exist.

You may do all of these things already (in which case, good for you! you
learned more in 12 weeks than a lot of Rails developers do in years). I just
called them out because (a) not doing them will be tremendously painful down
the road (individual XSS slipups are annoying but unlikely to kill you, but
vulnerabilities that allow people to dump your whole database are something
else) and (b) they are so easy to fix.

Good luck!

~~~
mhartl
Teaching good security practices was one goal of the _Ruby on Rails Tutorial_
(a resource mentioned in the OP). It uses attr_accessible for _every_ model
and uses find-through-association (emphasizing the security implications of
both), and it most assuredly does _not_ use the /:controller/:action/:id
pattern or backticks. It punts image upload over to Gravatar, and recommends
Paperclip for those who need custom uploads.

Having a PreauthController definitely sounds like a good idea, but it might be
a bit obscure for beginning developers. I'll consider it for inclusion as an
exercise in one of the chapters covering authorization, or maybe I'll include
it in more advanced _Rails Tutorial_ material down the road. Thanks for the
tip.

~~~
tptacek
All I can say is, I looked under the hood at the application we're talking
about and thought these might be useful suggestions. Particularly
attr_accessible.

I've found a lot of Rails apps over the last couple years that were diligent
about _having_ an attr_accessible in every model, but not diligent about what
went in the attr_accessible. Following the Rails idiom, they were doing all
their attribute assignment through update-style params[:model] model[foo]
model[bar] stuff, and attr_accessible "breaks" that.

The Rails tutorial is good (and ambitious) --- just know, this stuff trips up
solid, experienced Rails developers all the time.

~~~
danneu
When I was starting out, every tutorial seemed to assume that I even knew what
"mass assignment" implied. Creating a bunch of bad things at once? Changing a
lot of existing things in a bad way at once like their creator_id so a bad guy
could access them?

I think "mass assignment" and "attr_accessible" in tutorials should always
link to the API documentation[1] that explains the implications and the tools
at your disposal + example code.

[1]:
[http://api.rubyonrails.org/classes/ActiveModel/MassAssignmen...](http://api.rubyonrails.org/classes/ActiveModel/MassAssignmentSecurity/ClassMethods.html)

~~~
sc00ter
Worse still, I started off with _Beginning Rails 3_ by Apress, and it makes
only one obscure reference to attr_accessible, and not in the context of
security, doesn't mention mass assignment at all, and has no chapter on even
basic security. Beginners need to learn this stuff early, so Apress' oversight
is unforgivable. mhartl OTOH is to be applauded.

------
saltcod
The other thing I want to add is how much 'else' I learned while running
through Michael Hartl's tutorial.

Despite many years making websites, I really had no clue about basic http
methods — get, put, post, etc — and in fact, I didn't even realize what they
were. The other huge, huge thing for me was finally figuring out what REST is
all about.

Basically, the web runs on those few basic http methods, and using the REST
approach spells that out for you and cements it in your head.

I had an awesome jump-up-and-down moment when it finally clicked.

~~~
danneu
And 'else' things like Git, actually working with Github and Heroku, and
learning how to test in the same tutorial that's teaching you Rails.

------
freehunter
I get really annoyed when there is an element that follows me down the page as
I scroll. It's really distracting. I get even more annoyed when I have to set
up an adblock rule to make it go away.

Please, designers, stop doing this (and stop doing menu bars with the same
behavior). There's not much on your site that is important enough that I need
it to follow me everywhere.

------
saltcod
Fantastic post. Thanks so much for it. I decided to really dig into Ruby on
Rails after Christmas this year, after thinking/talking about it for years. I
was thrilled to hear that you really had no programming background—I think a
lot of us are in this boat.

I watched the Lynda.com videos on Ruby, and the one on Ruby on Rails (both
from Kevin Skoglund). I just watched enough of both to get fairly overwhelmed
and confused, then moved on to Michael Hartl's site. Things started to click
much better there—that's the best Rails resource I've seen to date.

Still though, After really digging in over the evenings and two weekends, that
nagging feeling started to set in—am I actually going to 'get' this? Am I
wasting my time? Is this going to take years? Will I ever get past
layouts/partials? Should I just go learn PHP / Javascript / iOS / something
else?

Did you feel like giving up? Or question the purpose/wisdom of learning Ruby
and Rails?

~~~
james-fend
Yes, it was the hardest/easiest thing to learn I've ever experienced.
Sometimes I was jumping out of my chair and then other times throwing things
against the wall.

Plenty of times I wanted to just give up.. during those points; I'd step back
and go take a break, go for a walk, do something.. other than think.

Programming is hard because it's full-time blitz mode thinking. I felt the
front part of my brain (is that where all the programming juice is held?) hurt
often in the beginning.

Do you have an actual product you want to work on?

~~~
tmh88j
I'd like to add to this simply because I had a very similar experience but
with PHP.

There were definitely times when I was extremely frustrated and wanted to give
up. There were a couple times when I had 5+ hour sessions and got nowhere,
then I'd come back the next day to realize it was a stupid mistake.

One thing I can't stress enough (and James has been saying it too), if you
don't have a final site, product, or app in mind you're probably going to get
bored and walk away for good. I tried to learn C++ a while back and gave up
because I didn't have anything in mind and the boring repetitive exercises
lead to nothing in the end.

~~~
james-fend
"then I'd come back the next day to realize it was a stupid" I couldn't agree
with that more!! Come back and you find out all you had to do was restart the
'Rails Server' or simply mis-spelled something.

------
tmh88j
Great write up. I experienced a similar adventure in learning PHP over the
past couple months and I completely agree that the first few weeks are by far
the hardest.

Late last summer a friend and I came up with a great idea but we lacked the
programming skills to create it ourselves. I knew a bit of HTML, a touch of
c++ , and PLC ladder logic programming(huge help, right?). It wasn't until
around October that I realized we were getting nowhere. I decided enough was
enough and I was going to learn how to program. I spent an entire weekend
reading and trying out zend's PHP 101 for beginners. Three months later and I
had created a user authentication system with messaging, friends lists,
administrative rights, and all sorts of other goodies. I was working a full
time job so I did this with my spare time.

Your site looks great by the way. Keep up the good work.

~~~
james-fend
thank you! how many hours total do you think you spent during the 3 months?

~~~
tmh88j
During the initial learning phase I wasn't as enthralled because who cares
what $this->someFunction($variable) means? I'd say I put in around an hour per
day for the first month and then once I got the hang of it, probably 2-4 hours
per day after that. I made sure to take off programming at least one day per
week so I wouldn't get burned out considering I was working full time too.

So, I'd estimate around 150-160 hours. I should've kept track. I plan on
learning ruby later on this year and I'll be sure to keep a record of that.

~~~
tmh88j
James, this is in response to what you said to my last comment. The reply
button wasn't showing.

Anyway, that 150-160 hours was to the point where I was comfortable enough to
sit down and code away. I'm still working on the system and I'm still learning
a lot. I'd also like to become a lot better with css/jquery. I know the basics
and not much more. A guy on my team is a front end whiz so I don't have to
worry about cramming that into my head right now.

------
jwong42
Hey James, very inspiring read. I've been following your story and progress on
the fastlane forum and glad to see that you had a successful launch! I've also
been learning to program myself but my language of choice was python and
django for framework. You are right that it takes some time to get through
that initial learning curve but once you reach that first stage and figure out
how to get past everytime you get stuck, it gets pretty exciting and fun.
Congrats and best of luck to you!!

------
GnomeChomsky
Any advice for getting started for someone without a Mac? I remember once
trying to learn and immediately stalling out during setup (lame, I know). I
have WinXP & Ubuntu, and would like to take a stab at this again no matter how
stupid I feel about not even being to able to install the damn stuff to start
with.

~~~
AznHisoka
Use Mac Leopard, and don't switch from 32 bit to 64 bit - you're gonna get a
massive headache getting all those gems you need to install. Also if you're
considering doing anything to do with image processing, consider NOT using
Mac. Installing stuff like PIL and ImageMagick can be hell

~~~
james-fend
Using MacPorts to install ImageMagick was hell. But when I used HomeBrew, it
was like night and day.

------
civild
I just had a look at Freelancify and registered, and I'm amazed that you did
it all in 12 weeks learning Ruby from scratch. Kudos!

Based on your experience, how do you think learning materials/tutorials could
be improved for people learning from scratch?

~~~
ams6110
I had a look at it too, and from a design standpoint it looks very nice. I am
not sure about your choices for project budget. For example, this description
was posted for bids:

 _Need Drupal developer to: - do PSD/HTML to Drupal theme for one new section
on the existing site. - Do additional module programming. - fix issues/error
on the site - Make the entire site work_

With a stated budget of $100--$300. I mean come on, that's ridiculously naive
on the part of the person who posted. If you could give bid-seekers some
guidelines on what to reasonably expect, e.g. some examples of what a budget
of $100-$300 might buy, it would help people get qualified bids.

------
spiredigital
Awesome work, James!

Your site looks really nice, and now you've got the ability to do design AND
program, which is a combo that isn't too common.

Best of luck with your site....

------
evanlong
XSRF:
[https://github.com/evanlong/security/blob/master/web/csrf/fr...](https://github.com/evanlong/security/blob/master/web/csrf/freelancify.html)

~~~
verroq
Doesn't the rails csrf token prevent that?

------
moreorless
Fantastic and inspirational writeup. Definitely will be forwarding the story
to my nephew who is starting to show interest in programming.

------
darushimo
thanks james and commenters saltcod and tmh88j for saying that the first few
weeks are the hardest. I'm banging away at the google python exercises and
nearly crying. knowing that other people are going through this headache too
gives me a bit of confidence to truck through.

~~~
tmh88j
Once you get through the basics, think of a couple small programs to write to
test out your new skills and you'll be sure to encounter new problem. Some of
the first programs I wrote in PHP included sorting and ordering a list of
numbers and letters that were entered, a pig latin converter, and then to get
the hang of MySQL, I created some simple database entries.

For the first month I was constantly referencing other code online to figure
out how to create my programs. After a while I found myself looking less and
less at existing code and I was able to simply type away.

------
daylonsoh
James, I'm kinda in a similar situation like your old-self and now you have a
gun.

------
instakill
Did you go about this project doing TDD/BDD?

~~~
SkyMarshal
No, sounds like he used PM [1].

1\. <http://programming-motherfucker.com/>

~~~
SkyMarshal
If I could edit that, I'd add a smiley or something to make it clear I didn't
intend to be an ass. Meant that to be funny.

------
mellifluousmind
As someone with programming background, I actually wish there are more stories
on the opposite direction (programmer who gets kickass awesome in UI design
(HTML + CSS)).

I think that the complexity of CSS compatibility (what browser supports what
not... even there are minor quirks between Firefox & Chrome, not just IE..
don't get me started on IE7 & 8 either), it is very easy to raise a white flag
and say "that is it..I am going back to deal with backend only tasks, nothing
that consumer will see on the surface).

Perhaps, OP already has a knack for UI design (as he/she mentioned in the post
that he/she is a UI designer by trade before Ruby), so kudos for getting a
nice grip on Rails. As for me, I wish I can master the UI design etc.

~~~
randomdata
I sort of built my skills in unison (had an interest in both programming and
design since I was a kid), but my career has tended towards the development
side, so I guess you could say that I am a programmer by trade that picked up
design on the side. Whether or not I am "kickass" is subjective, but people
seem generally happy with my work.

The biggest challenge I find is that people do not take designer programmers
seriously. Those who do just enough programming to support their interfaces
seem to be respected, but as soon as I dive in writing some low level
component in C, as an example, my design skills are immediately discounted, it
seems.

Programming _is_ design, in my opinion. The way you structure your code,
getting the indents and spacings just right to be pleasing to the eye, are the
exact same skills you need when you're shifting pixels in photoshop. Thinking
about how the next programmer will interpret the meaning of your code is the
same skill you need when thinking about how a user will use your interface. I
feel the only thing limiting a programmer from becoming a good designer is
practice.

~~~
kaylarose
I have the opposite background, but similar anecdotes. Spent all of high
school and college in various art or design-focused curriculum and degrees.
Inevitably ended up taking a few dev courses, but was only marginally
interested. My first job after college was as a web designer in a software
shop where I quickly realized that "real-world" programming mixed aesthetics
and creativity with logic and really hard problems, was immediately hooked and
started absorbing everything (even SICP!) in my quest to become a better
developer.

Like yours, my left-brain intuitively sees patterns and (un)readabilty in
code, beauty in simplicity, and has empathy for users/novices. My right-brain
solves the problems, connects the top to the bottom, and is cold-and-
calculating about the inner-workings.

It's also my experience, that if you are design-forward people discount your
programming skills (all the more reason to prove them wrong) and if you are
development-forward people discount your creative side ("oh, I _totally_ trust
your opinion, but just to be on the safe side....").

IMHO Diversity of skills gives you insight into your work and the world around
you. Even if you are not a natural you still gain new perspective. Hell, even
knowing that you aren't any good is half the battle! I am good at _executing_
other people's ideas, and intuitively knowing what looks good - but struggle
coming up with an original _truly unique_ artwork from scratch. On the other
hand, Give me an empty vim buffer...

------
theDaveB
I can't get the tryruby.org site to work properly. If I do anything wrong it
just locks up and I have to refresh the browser window.

For instance at the "type 2 + 6" question, if I type 2+6 it freezes. If type 2
+ 6 it's fine.

Running OSX Lion and Google Chrome.

Dave

------
fragileandys
is this a joke? if so its funny... when i click the link i get: "Error
establishing a database connection", haha

~~~
jemka
It's likely a result of a cheap host server not being able to handle the
traffic. Not a reflection of OP's programming abilities.

~~~
james-fend
Yep. That's exactly it, it's on a cheap server and too much traffic. Anybody
experience this before and/or know some quick solutions?

~~~
kabuks
You mentioned Heroku in your post. Why did you decide not to host there?

~~~
james-fend
Good question. The wordpress blog (webstartup.me) is on a cheap server.
Freelancify is hosted on Heroku.

~~~
loucal
jekyll on S3 is a pretty killer combo for a cheap blog that scales infinitely
and automatically. You'll probably like it, especially since you're a ruby
guy.

~~~
james-fend
thank you for the suggestion, will look into that. The popularity of the posts
def caught me off-guard..

