Advice/tools for working on a large existing rails application? [closed] - ruby-on-rails

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I recently joined a new company with a large existing codebase. Most of my experience has been in developing small-medium sized apps which I was involved with since the beginning.
Does anyone have any useful tools or advice on how to begin working on a large app?
Do I start at the models and move to controllers? Are there scripts to visually map out model relationships? Should I jump in, start working on it and learn the apps structure as I go?

Railroad should help you understand the big picture. It generates diagrams for your models and controllers.

I found unit tests to be the most efficient, effective and powerful tool. So, before making any change, make sure your application has a minimum LOC so that you won't break any existing feature working on.
You should care about unit tests (of course I'm talking about unit/functional/integrational tests) because:
they ensure you won't break any existing feature
they describe the code so that you won't need tons of comments everywhere to understand why that code fragment acts in that way
having test you'll spent less time debugging and more time coding
When you have tests, you can start refactoring your app.
Here's a list of some tools I usually work with:
Rack::Bug
New Relic
You might want to view some of the wonderful Gregg's videos about Scaling Rails to get more powerful tools.
Also, don't forget to immediately start tracking how your application is performing and whether it is raising exceptions. You can use one of the following tools
Hoptoad
Exceptional
If you need to fix some bug, don't forget to reproduce the issue with a test first, then fix the bug.

Not specific on Rails, but I would start reading the requirements and architecture documentation. After that get familiar with the domain by sketching the models and their relationship on a big sheet of paper.
Then move on to the controllers (maybe look at the routes first).
The views should not contain that much information, I guess you can pretty much skip them.
If you still need to know more, the log of the versioning system (given they use one) is also a good place to get to know how the project evolved.

When I've been in this situation, I try one of three things:
Read all the code top to bottom. This lets you see what code is working, and you can report progress easily (I read through all the view code this week). This means you spend time on things that may not be helpful (unused code) but you get a taste of everything that is there. This is very boring.
Start at the beginning and go to the end. From the login page or splash screen, start looking at that code, then the next page, then the next page. Look at the view, controller, and database code. This takes some time, but it gives you the context for why you need that code or database table. And it allows you do see most often the ones that get used in the most places. This is more interesting.
Start fixing bugs. This has the benefit of showing progress on your new project (happy boss) taking work from other people (happy co-workers) and learning at the same time (happy developer). It provides the context of number 2, and you can skip rarely used code from number 1. This is the most interesting way for me.
Also, keep track of what you've learned. Get a cheap spiral-bound notebook and write down an outline of what you've learned. Imagine yourself giving a talk on the code you're learning about or bug you're fixing. Take enough notes to give that talk, and spice it up with a factoid or two to make it interesting. I give my notebooks dignity and purpose by calling them "Engineering Notebooks", put a title on the front (my name, company, date), and bringing them to every meeting. It looks very professional compared to the guys who don't show up with paper to take notes. For this, don't use a wiki. It can't be relied upon, and I spend a week playing with the wiki instead of learning.
As mentioned above, being the new guy is a good chance to do the things nobody ever got around to like unit tests, documenting processes, or automating running tests. Document the process to set up a new box and get all the software installed to be productive. Take an old box under someone's desk and put a continuous integration install on it, and have it email you when the tests fail. You can forward that email whenever someone else checks in code that breaks the tests. Start writing tests to figure out how things work together, esp. if there aren't any/very many tests.
Try to ask lots of questions in one-on-one situations. This shows you're engaged and learning, and it helps you find the experts in the different parts of the app. On a big project you may need to go to one person for one topic and a different person for other topics. It also helps identify who thinks they know more than they really do or who talks more than you really need.

Related

How do i break Objective-C (iOS app) code into an object oriented design [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
I'm starting a massive project for the first time. I was supposed to be one of the developers on this big project, and all of a sudden, the lead developer and his team backed out of the contract. Now I'm left managing this big project myself with a few junior developers under me and I'm trying to get a firm grasp on how this code should be broken up.
Logically, to me, the code should be broken up by the screens it has. I know that might not be how it SHOULD be done. so tell me, how SHOULD it be done? The app has about 6 screens total. It connects to a server, which maintains data about all other instances of the app on other phones. You could think of it as semi-social. it will also use the camera feature in certain parts, and it will definitely use geolocation. probably geofencing. It will obviously need an API to connect to the server. most likely more APIs than just the 1. I cant say much more about it without breaking an NDA.
So again, my question pertains to how the code should be broken up to make it as efficient as possible. Personally, i'll be doing little coding on the project. probably mostly code reviews, unit testing and planning. Should it have 1 file per screen, and parts that are repeated should have their own classes? should it be MVC? We're talking a 30k line app here, at its best and most efficient. is there a better way to break the code apart than the ways I've listed?
I guess my real question is, does anybody have good suggestions for books that would address my current issue? code clean was suggested, that's a good start. I've already read the mythical man month and code complete but they don't really address my current issue. i need suggestions for books that will help me learn how to structure and plan the creation of large code bases
As I'm sure you know this is a pretty vague question you could write a book answering it. In fact, I would recommend you read one, like Clean Code. But I'll take a stab at a 10,000 foot level overview.
First if you are doing an iPhone app, you will want to use MVC because that is how Apple has setup their frame work. That means each screen will have (at least) a view-controller, possibly a custom view or NIB.
In addition you will want your view controllers pointing to your model (your business objects) and not the other way around. These objects should implement the use cases without any user interface logic. That is what your view-controller and view will be doing.
How do you break apart your use cases? Well, that's highly specific to your program and I won't be able to tell you with a (lot of) details. There isn't a single right answer. But in general you want to isolate each object from other objects as much as possible. If ever object reference ever other object, then you don't really have an OO design, you have a mess. Especially when you are talking about unit tests and TDD. If when you test one part you end up pulling in the whole system, then you are not testing just one small unit, are you?
Really though, get a good book about OO design. It's a large subject that nobody will be able to explain in a SO answer. I think Clean Code is a good start, maybe other people will have other suggestions?

How do you convince your manager that your project needs a huge refactoring? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I have joined a rails project as a contractor. The project has been going for more than a year. The code is written by about 10 different developers and most of them are contractors as well. They have different code style. Some of them came from Java. The code has horrible scores with metric_fu. Many functions are very long (100 - 300 lines). Some functions have insane amount of logical branches, loops, and recursions. Each request generates a ton of sql queries. Performance is very bad. Many obsolete code that are never used but never got the chance to be cleaned up. The core architecture is plain wrong or over engineered. Code coverage is only about 25%. Views and partials are chaotic and terrible to read and understand.
The manager is in a position trying to satisfy the CEO by continuously adding new features, however newer features are increasingly hard to get implemented correctly without breaking something else. He knows the code is bad, but doesn't want to put too much effort in fixing them as refactoring will take too long.
As a contractor / developer, what is a good way to clear this situation and convenience the Manager or CEO to partition some time for refactoring?
Related Questions
How can I convince skeptical management and colleagues to allow refactoring of awful code?
How to refactor on a budget
Dealing with illogical managers
In my limited experiance:
It's impossible to convince a manager that it's necessary to set aside time to refactor. You can make him aware of it, and reinforce the point every time that you run into an issue because of bad code. Then just move on. Hopefully your boss will figure it out.
It's quite common to get in on a running project and think "this is total junk". Give it some time. You might begin to see a pattern in the madness.
I've been in similar situation. There are basically only two options:
You get some relaxed time and you may be granted time to refactor something
Due to the bad code further development of some component comes to a stall. You can't proceed to add anything because every little change causes everything else to stop functioning. In this emergency case you will get a "go" with refactoring.
I have just answered in some other question, my horror story:
https://stackoverflow.com/questions/1333077/dirty-coding-tricks-to-deliver-project-on-time/1333095#1333095
I have worked on a project where dirty tricks were the main driving principle of the development. Needlees to say, after some time these tricks have started to conflict with each other. In one analytics component, we had to implement the other very dirty trick - to hide away those calculated values which due to the conflicting tricks were not calculated properly. Afterward, the second level tricks started to conflict and we had to create tricks to deal with those. Ever since, even the mentioning of this component makes me feel horror that I may have to work on it again.
It's exactly the second situation where refactoring is the only way out.
In general, many managers without a technical background (actually, those who come from bad programmers as well) neither care nor understand the value of quality code and good architecture. You can't make them listen until something interrupts their plans, like a blow of "non-implementable" features, increasing and reoccurring bugs, customer requests that cannot be satisfied and so on. Only then understanding of the code problems may come for the first time. Usually, it's too late by then.
Refactoring code that sucks is part of coding, so you don't need to get anybody's approval unless your manager is watching your code and or hours VERY closely. The time I save refactoring today is time that I don't have to bill doing mad tricks to get normal code to work tomorrow (so it works out, in the end).
Busting up methods into smaller methods and deleting methods that are not used is part of your job. Reducing DB calls, in code that you call, is also necessary so that your code doesn't suck. Again, not really refactoring, just normal coding.
Convincing your manager depends on other factors, including (but not limited to) their willingness to be convinced, and your ability to convince.
Anyway, what is massive refactoring in RoR? Even if the "core architecture is just plain wrong," it can usually be straightened out a bit at a time. Make sure you break it into chunks /use branches so you don't break anything while you're busy fixing.
If this is impossible, then you come back to the social question of how to convince your manager. That's a simple question of figuring out what his/her buttons are, and pushing them without getting fired nor arrested. Shaming, withholding food, giving prizes, being a friend, anonymous kidnapping threats where you step in and save the day... It's pretty simple, really: creativity is the key!
Everyone is missing a point here:
Refactoring is part of the software development life cycle.
this is not only a RoR or any specific project but any other software development project.
If somehow you could convince your PM why it is important to refactor the existing code base before adding any new feature, you're done. You should clearly tell your PM that any further addition of new feature without any refactoring will take more time than required. And even if the feature is added, somehow, bug resolving sessions will take even more time since the code is very bloat and unmaintainable.
I really don't understand why people forget the principle of optimise later. Optimising later also includes refactor later IMHO.
One more thing, when taking design decisions, you should tell the consequences, good or bad, to your PM very very clearly.
You can create a different branch(I assume you are using git) for refactoring and start adding new feature in some other branch if your PM insist on adding new feature along with refactoring.
A tricky one, i have recently worked in such a company... they were always pushing for new things, again they knew it was bad, but no matter how hard I pushed it - i even got external consultants in to verify my findings - they seen it as a waste of time.
Eventually they seen the light... it only took multiple server crashes and at one point almost a full 8 days of no website to convince them.
Even at that they insisted it 'must' be the hosting service.
The key is to try and quantify how long their site will last before it crunches, and get some external verification to back you up - 'they' always trust outsiders who know nothing about your app! Also, try - if you can - to give a plan that involves gradual replacement at worst, and a plan for how long it would take to do that way. Also a plan for if 1 or 2 bodies were working on a complete rewrite hwo long it might take - but be realistic too or it will bit you in the bum! If you go that route (which is what we done) you can still have some work on the existing site as long as you incorporate it into the new.
I would suggest that you put focus on things that they can see for themselves, that is, they will surely notice that the application is slow in some functionalities, so pick up one of them and say something like "I can reduce the waiting time here, can I take some time to improve this specific thing?" (more well said, but you got the point :P).
Also consider that 10 developers before you did not refactor the code base, this may mean that it is a monstruos task, likely to make the situation worse, in this situation if something will go wrong after the refactoring it will be your fault if the program does not work properly anymore.
Just a though, but worth considering.
I'd take one small chunk of application and refactored and optimized it 'till it shines (and I'd do it in my personal time in order not to annoy my manager). Then you'll be able to show your manager/CEO the good results of refactoring and SQL optimizations.
If there is a need to refactor then the code will speak for itself. Minor refactoring can continue in during development. If you cant convince the manager then probably you should rethink if its necessary at all.
However if it is absolutely necessary then constructing metrics of development activities and the benefits should convince the manager.
I think one of options would be to highlight to the manager how re-factoring the code base now will save time (i.e. money) in the long-run. If the project is expecting to be running long term then making the changes now will clearly save you and other developers time in the future.
Best to use an example of a feature you've worked on estimating how long it would have taken if you had the cleaner code to work from in the first place. Good luck!
I am in same position right now, but with an agreement with the manager that, when the new feature should be implemented in some existing module to re-factor the module too (if it needs re-factoring), we are struggling now with the code created 4-5 years ago and definitely I find out that the re-factoring someone else s code is not trivial nor amusing to do, but very very helpful for the future re-use.

Suggest a web development approach [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
I work as a PHP developer, and my boss is driving me crazy. He calls me every now and then, gives me tasks even when the previous tasks haven't been completed. Forbids me from meeting with clients and tells me incomplete specification verbally or over the phone, and expects to have working applications from the first deployment. Can any body suggest a way to curb this guys enthusiasm?
document what you are spending your time doing.
document requirements as they come in (through whatever channel)
provide both of these to your boss as frequently as necessary in order facilitate conversation about missing requirements or prioritization of your time
Start looking for another job and give him a pre-notice. This will curb his enthusiasm. Some people are to be avoided at all costs.
//Only two things are infinite, the universe and human stupidity, and I'm not sure about the former." -- Albert Einstein
Talk to him about the communication problems. It's usually a two-way problem. If he's giving you incomplete specs, why aren't you asking for more complete ones?
If you just want to stick it to him, then find a better job. If you're committed to making it work, then put some serious thought into the root of the problems you're having, and get him on board with helping you solve them.
I'd suggest having some sort of task list somewhere so that when your boss adds something to this list, he can see what you are doing and have estimates for how long some things will take.
As for the requirements being incomplete, this is why some like Agile approaches where you would get your boss in to test something regularly to verify that it is acceptable before putting something into production.
As others have mentioned who can type faster than me, one thing you can do is to try setting up some type of project management/bug tracking system for him to use. I've used FogBugz with success which requires no installation and has a free plan for small teams. You can setup an email account that he can send requests to.
When proposing this to your boss, do it in a way that will show that your goal is to help keep track of your tasks and priorities. But also be prepared for additional work. If he is agreeable to it he may want to see frequent status reports and where you are spending all of your time.
If you can get more complete specifications this can help drastically. It'll help you understand the project better. It'll help you estimate time for completion. And my favorite -- it'll help prevent double-work. There's nothing worse than getting incomplete requirements, building something wrong, and then finding out that you need to redo it.
If you can I'd try to find a good way to suggest this to your boss without stepping on any toes. If he understands the benefits he may be more open to the idea of being more thorough with you. What it'll really do is make you more efficient at your job.
Oh, and you may want to take a look at my answer to this question relating to time estimation:
How am I supposed to know how many days something will take?
The other suggestions of keeping things in writing at least for yourself are valid. However, for the kind of boss you describe with which I have some familiarity, it may not work.
Some bosses just never learn or already know what they are doing is wrong and do it anyway because to them, saying "yes" to the client and getting a signoff on a bigger contract today is more important than programming methodology that could delay a payment for 3 weeks (testing? why do we need to test? you tested it, right? two weeks for function X?! all you have to do is add a button, right?).
To many bosses, programming is just one of the tools needed to run their business. To them, it's a business to make money and programming methodology/quality is secondary.
What you do to keep yourself sane and safe if you want to stay with this boss is at least keep written records of every request and when problems come up, remind him why they happened. If possible, ask that all specs be delivered at least by email instead of verbally.
You always have the choice of going somewhere else if things don't improve.
Good luck.
I have struggled with this same problem at a few jobs.
I've observed that there is a type of programmer who can survive in this environment: one who simply works on whatever the boss says is the priority of the moment, and doesn't worry about deadlines at all. Just keep putting things on the back burner, and resume working on them the next time the boss asks for it. Endure the occasional tirade from your boss when something he asked you to start 12 months ago isn't done yet, because you've been working on whatever he gives you.
If you aren't comfortable with that sort of existence (and I would not be), then the best strategy I can suggest is that you have an open conversation with your boss about it:
It's important to me to do a good job,
but I feel like the work requests are
coming in faster than I can complete
them. I know that priorities
inevitably shift, so I'd like some
help from you to understand when this
happens, and how to balance my time
among the tasks to best meet your
needs. Can we talk about how to stay
in sync about priorities?
If the tasks can't be prioritized,
then I need you to understand that I
can't be productive on so many tasks
at once. It's just not humanly
possible. Have you considered hiring
additional programmers so we can
balance the workload and get it all done
in a timely way?
If he tries to stall or contradict or tells you to "work smarter, not harder" then you can escalate:
Let me put it another way: if you continue to give me tasks at the rate you have been, but don't prioritize them clearly, then you are going to hire another programmer. Whether this hire is your second programmer, or else my replacement, is up to you.
Basically, communication is good. Start by being diplomatic and phrasing everything in terms of how you contribute to his success. But increase the degree of bluntness until it sinks in.

How to deal with poorly informed customer choices [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
Here's a scenario I'm sure you're all familiar with.
You have a fairly "hands off" customer, who really doesn't want to get too involved in the decision making despite your best efforts.
An experienced development team spend hours discussing the pros and cons of a particular approach to a problem and come up with an elegant solution which avoids the pitfalls of the more obvious approaches.
The customer casually mentions after a quick glance that they want it changed. They have no understanding of all the usability / consistency issues you were trying to avoid in your very carefully thought out approach.
Despite explanations, customer isn't interested, they just want it changed.
You sigh and do what they ask, knowing full well what will happen next...
3 weeks later, customer says it isn't working well this way, could you change it? You suggest again your original solution, and they seize on it with enthusiasm. They invariably seem to have had a form of selective amnesia and blocked out their role in messing this up in the first place.
I'm sure many of you have gone through this. The thing which gets me is always when we know the time and effort that reasonably bright and able people have put in to really understanding the problem and trying to come up with a good solution. The frustration comes in contrasting this with the knowledge that the customer's choice is made in 3 minutes in a casual glance (or worse, by their managers who often don't even know what the project is really about). The icing on the cake is that it's usually made very late in the day.
I know that the agile methodologies are designed to solve exactly this kind of problem, but it requires a level of customer buy in that certain types of customers (people spending other peoples money usually) are just not willing to give.
Anyone any clever insight into how you deal with this?
EDIT: Oops - by the way, I'm not talking about any current or recent customer in this. It's purely hypothetical...
Make your customer pay by the effort you are putting into designing and developing the solution to their problem.
The more you work, the more you get. The customer will have to pay for his mistakes.
Customer will eventually learn to appreciate your experience and insight in the programming field.
Niyaz is correct, unfortunately getting a customer buy-in is difficult until they have been burned like this once before.
Additionally describe to the customer the scenario above and state how much extra it would cost if you went three or four weeks down the line and had to rewrite it due to a change and then let them use the prototype. It may take a few days to put one together so they can see both options (theirs [the wrong way], and yours [the right way]). Remember they are paying you not only for your ability to program but also your experience and knowledge of the issues which crop up.
Whatever the decision the customer makes, ensure that you get it documented, update your risks register for the project with the risks that the chosen implementation will incurr and speak to the project manager (if its not you) about the mitigation plans for them.
I agree with Niyaz. However at the time the customer suggests the change you should work out what the impact of the change will be, and how likely that impact is to happen. Then ask whomever is responsible (it's not always that customer) for the deliverable if they approve the change.
Making the impact clear (more cost, lower reliability, longer delivery time etc) is very important to helping the customer to make a decision. It's very important to describe the impacts on the project or their business in a factual way, and assess how likely that impact is to occur. "Maybes" and "i feel" are very ignorable.
After that as long as the right people approve the change and as long as they pay for it.. well you did give them what they wanted :)
One thing we have done with some success in the past in these kinds of situations is to hand the issues over to the client.
"OK, you want to change it - this is
what will happen if you do that. These
are the issues involved. You have a
think about how you'd like it to work
and then get back to us".
This approach doesn't tend to yield good solutions (unsurprisingly) but does tend to let the client see that it's not a "gut feeling", wild stab in the dark kind of question.
And failing that, it usually makes them stop asking you to change it!
Usually a scenario like this is caused by 2 things. The ones that are supposed to give you the requirement specifications are either don't put their hearts into the project because they have no interest in it, or because they really have no idea what they want.
Agile programming is one of the best ways, but there are other ways to do this. Personally I usually use a classic waterfall method, so spiral and agile methods are out of the questions. But this doesn't mean that you can't use prototypes.
As a matter of fact, using a prototype would probably be the most helpful tool to use. Think about the iceberg effect. The secret is that People Who Aren't Programmers Do Not Understand This. http://img134.imageshack.us/my.php?image=icebergbelowwater.jpg
"You know how an iceberg is 90% underwater? Well, most software is like that too -- there's a pretty user interface that takes about 10% of the work, and then 90% of the programming work is under the covers...." - Joel Spolsky
Generating the prototype takes time and effort but it is the most effective way to gather requirements. What my project team did was, the UI designer was the one that made the prototypes. If you give the users a prototype (at least a working interface of what the application is going to look and feel like) then you will get lots of criticism which can lead to desires and requirements. It can look like comments on YouTube but it's a start.
Second issue:
The customer casually mentions after a quick glance that they want it changed. They have no understanding of all the usability / consistency issues you were trying to avoid in your very carefully thought out approach.
Generate another prototype. The key here are results that the users would like to see instead of advice that they have to listen to.
But if all else fails you can always list the pros and cons of why you implemented the solution, whether or not the particular solution they like is not the one you insisted on. Make that part of the documentation as readable as possible. For example:
Problem:
The park is where all the good looking women jog to stay in shape. Johnny Bravo loves enjoying "mother nature's beauty", so he's lookin to blend in... you know... lookin all buff and do a little jogging while chasing tail.
Alternative Solutions:
1) Put on black suede shoes to look as stylish as you can.
2) Put on a pair of Nike's. Essential shoes for running. Try the latest styles.
Implemented Solution:
Black suede shoes were top choice because... well because hot mommies dig black suede shoes.
Or else, if they won't pay for the effort, just avoid putting that much resources into the solution of the problem, and just give them exactly what they've asked for and then think about it after the three weeks have passed.
Somewhat frustrating, yes, but that's the way it'll always be with that kind of customers. At least you won't be losing money.

How do you read an existing Rails project?

When you start working on an existing Rails project what are the steps that you take to understand the code? Where do you start? What do you use to get a high level view before drilling down into the controllers, models, helpers and views? Do you have any specific techniques, tricks or tools that help speed up the process?
Please don't respond with "Learn Rails & Ruby" (like one of the responses the last guy who asked this got - he also didn't get much response to his question so I thought I would ask again and prompt a bit more). I'm pretty comfortable with my own code. It's sorting other people's that does my head in and takes me a long time to grok.
Look at the models. If the app was written well, this should give you a picture of its domain model, which is where the interesting logic should live. I also look at the tests for the models.
The way that the controllers/views were implemented should be apparent just by using the Rails app and observing the URLs.
Unfortunately, there are many occasions where too much logic lives in controllers and even views. That means you'll have to take a look into those directories too. Doubley-unfortunate, tests for these layers tend to be much less clear.
First I use the app, noting the interesting controller and action names.
Then I start reading the code for these controllers, and for the relevant models when necessary. Views are usually less important.
Unlike a lot of the people so far, I actually don't think tests are the place to start. I think they're too narrow, too focused. It'd be like trying to understand basic physics/mechanics by first zooming into intra-molecular forces and quantum mechanics. I also think you're relying too much on well-written tests, and in my experience, a lot of people don't write sufficient tests or write poor tests (which don't give an accurate sense of what the code should actually do).
1) I think the first thing to do is to understand what the hell the app actually does. Use it, at least long enough to build an idea of what its main purpose is and what the different types of data might be and which actions you can perform, and most importantly, why.
2) You need to step back and see the big picture. I think the best way to do that is by starting with schema.rb. This tells you a few really important things:
What is the vocabulary/concepts of this project. What does "User" actually mean in this app? Why does the app have both "User" and "Account" models and how are they different/related?
You could learn what models there are by looking in app/models but this will actually tell you what data each model holds.
Thanks to *_id fields, you'll learn the associations between the models, which helps you understand how it all fits together.
I'd follow this up by looking at each model's *.rb file for (hopefully) comments, validations, associations, and any additional logic relevant to each. Keep an eye out for regular ol' Ruby classes that might live in lib/.
3) I, personally, would then take a brief glance at routes.rb as it will tell you two key things: a brief survey of all of the actions in the app, and, if the routes and controllers/actions are well named and thought out, a quick sense of where different functionality might live.
At this point you're probably ready to dig into a specific thing you need to learn. Find the controller for the feature you're most interested in and crack it open. Start reading through the relevant actions, see which models are involved, and now maybe start cracking open tests if you want to.
Don't forget to use the rest of your tools: Ruby/Rails debuggers, browser dev tools, logs, etc.
I would say take a look at the tests (or specs if the project uses RSpec) to get an idea at the high-level of what the application is supposed to do. Once you understand from the top level how the models/views/controllers are expected to behave, you can drill into the implementations.
If the Rails project is in a somewhat stable state than I have always been a big fan of using the debugger to help navigate the code base. I'll fire up the browser and begin interacting with the app then target some piece of functionality and set a breakpoint at the beginning of the associated function. With that in place I just study the parameters going into the function and the value being returned to get a better understanding of what's going on. Once you get comfortable you can modify the functionality a little bit to ensure you understand what's going on. Just performing some static analysis on the code can be cumbersome! Good luck!
I can think of two reasons to be looking at an existing app with which I have no previous involvement: I need to make a change or I want to understand one or more aspects because I'm considering using them as input to changes I'm considering making to another app. I include reading-for-education/enlightenment in that second case.
A real benefit of the MVC pattern in particular, and many web apps in general is that they are fairly easily split into request/response pairs, which can to some extent be comprehended in isolation. So you can start with a single interaction and grow your understanding out from that.
When needing to modify or extend existing code, I should have a good idea of what the first change will be - if not then I probably shouldn't be fooling with the code yet! In a Rails app, the change is most likely to involve view, model or a combination of both and I should be able to identify the relevant items fairly quickly. If there are tests, I check that they run, then attempt to write a test that exposes the missing functionality and away we go. If there are no tests then it's a bit trickier - I'm going to worry that I might inadvertently break something: I'd consider adding tests to give myself a more confidence, which will in turn start to build some understanding of the area under study. I should fairly quickly be able to get into a red-green-refactor loop, picking up speed as I learn my way around.
Run the tests. :-)
If you're lucky it'll have been built on RSpec, and that'll describe the behavior regardless of the implementation.
I run rake test in a terminal
If the environment does not load, I take a look at the stack trace to figure out what's going on, and then I fix it so that the environment loads and run the tests again
I boot the server and open the app in a browser. Clicking around.
Start working with the tasks at hand.
If the code rocks, I'm happy. If the code sucks, I hurt it for fun and profit.
Aside from the already posted tips of running specs, and decomposing the MVC, I also like:
rake routes
as another way to get a high-level view of all the routes into the app
./script/console
The rails irb console is still my favorite way to inspect models and model methods. Grab a few records and work with them in irb. I know it helps me during development and test.
Look at the documentation, there is pretty good documentation on some projects.
It's a little bit hard to understand other's code, but try it...Read the code ;-)

Resources