What parts of a Ruby-on-Rails application (with reasonably expressive unit tests) should have RDoc? [closed] - ruby-on-rails

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 5 years ago.
Improve this question
I'm developing an open-source web application on top of Rails. I'd like to make my code as easy to understand and modify as possible. I'm test-driving my development with unit tests, so much of the code is "documented" through test cases (what each controller action expects as input, what instance variables are set for output, how helpers should be called, what business logic the models incorporate, etc.). And on top of that, Rails' conventions should make a lot of documentation unnecessary where my code conforms to them.
So, where's the balance between having a well-documented Rails application and trying to obey Don't Repeat Yourself? Are there any good blogs or articles with guidance on what (RDoc) documentation is really helpful in a Rails app, and what's just waste?

OK, not at all sure this is the right thing, but here's what I decided to do:
First, I thought that another Rails developer would be familiar with at least the intent of all of the code I wrote in the standard models, views, controllers directories. So, I started adding RDoc in other source files. It turns out that I'd built up a fair collection of code in lib/helpers and app/helpers, so started there. I wrote fairly typical function-level documentation for each helper method, focusing on intent and making sure I'd spelled out the things that the method and argument naming was mnemonic for. I didn't describe most of the corner cases, argument interactions, or error checking, leaving those details to a reading of each method's unit tests.
I found that while I was doing this, there were quite a few changes I made to method signatures, rather than having to document having done something stupid. (Have you read Clean Code by #unclebobmartin? I think it's great on all fronts, but especially on naming and self-documentation.) So, in addition to being an RDoc-adding exercise, I ended up spending a significant amount of time on (needed) refactorings--things that hadn't occurred to me in the refactoring pass after I'd first written the code because I didn't have enough distance yet. Perhaps 80% of the time I spent "adding RDoc" went into the code in my "helpers" directories, and the majority of that was refactoring rather than writing. So, even if nobody ever reads the RDoc itself, I think this was a valuable exercise and I'm very happy I spent the time
Next, I turned to my Controllers. I left the default single-line comments matching what scaffolding generates on each controller method as the first line of the RDoc (e.g., "# GET /"). For methods that do just the standard Rails thing, I didn't add any other documentation. I found that the unique things I'd done in my controller methods that were worth documenting had to do with what they return (e.g., data formats other than HTML), what they're for (actions beyond the standard REST model, like those intended to service Ajax requests), and whether they use a non-standard URL format. (This was really documentation of my route configuration, but since config/routes.rb isn't used to generate RDoc....) I didn't describe the behavior of my actions at all, feeling that my automated tests sufficiently covered all of the cases/behaviors someone would need to know. Finally, I added class-level comments mentioning the model class that the controller manipulates, not because people can't guess, but so that there'd be a convenient link in the generated HTML page.
Last, I worked on my models. Again, I didn't document behaviors (business logic), considering my unit tests to be sufficient here. What I did do was remind readers that field definitions are in db/schema.rb (felt silly, but if a developer new to Rails was trying to figure things out, being reminded of the base names for all the magic methods couldn't hurt). I also realized that lots of my models' behaviors were implemented through Rails' declarative helper methods called directly by the model classes (validates_..., belongs_to, etc.). Rather than trying to describe what this stuff accomplishes (after all, the desired model behavior is "described" by the tests), I just put in a reminder to look at the model source. (It's a shame RDoc isn't aware enough of Rails conventions to extract and document these things like it does Ruby constant definitions.)
And that was that. Perhaps a little more RDoc than I needed to write, but I think that it is light enough that it will get maintained as the code evolves, and it doesn't overlap at all with things "expressed" by my unit tests. Hopefully, it has filled the gap between what a Rails developer can infer from convention and what you're only going to figure out from the source. (Although I'm now noticing a growing impulse to pull more pieces from my views into helpers, even though they're not reused and it would mean losing ERB's inline HTML, just so that I can write descriptions for them. Go figure.)

My short answer: rdoc your models, since they are truly unique to your application.
But it sounds like you are building a web-application, so the argument could be made that you should rdoc other pieces, too.

Document anything that is not crystal clear from reading the code. Self-documenting code is easily achieved with Ruby, but crafty logic needs comments! Try to put yourself in the shoes of a project newbie when deciding if something needs rdoc. Odds are that if you're thinking about whether or not it needs it, it does. Lastly, I wouldn't rely on test sources to provide documentation for your application code. I know that if I jumped on a project and was left scratching my head as to why a model is behaving a certain way I wouldn't run immediately to the unit test for answers.

Related

Is testing relations in Rails considered to be a best practice? [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 4 months ago.
Improve this question
Wondering if testing of a relations in Rails widely considered to be a best practice or not.
We have disagreement on the team on testing relations.
IMO it's redundant, i.e. to have each has_many :people to be tested with should have_many(:people) as it looks repetitive, just copy-paste from model to a test - i.e. I cannot imagine it stop working or some other workflow break it, the only way to break it - is just remove or change the line (but if someone just changing code randomly that someone can also just remove the test as well). Moreover it doesn't actually test relation (like if Company returns people who have appropriate company_id and if company destroyed - people are actually destroyed - as it can actually fail in case of destroy validation or foreign key) but it just test that relation is specified.
And we don't test like that class respond to every single method but if we do test - we test what method does.
As we don't test other static things, like templates (like simple HTML with no logic) - we assume rails will generate specified HTML, it's impossible to break unless someone just change it.
At the other hand there is an argument can be made that relations are extremely important part of the app and in effort to have 100% coverage that also should be tested.
Usually in case of disagreements we look to best practices but I cannot find any mention of relation tests - neither to do it or not.
Can you please help me to find out is it common practice or not. (links to best practices that says about that or similar thing or your experience working with those)
Thank you in advance
You've asked an opinion-based question that is hard to answer with sources, so you might need to rethink your question. However I'll give it a try.
I don't know about best practices, but in my opinion anything that can be "fat-fingered" should be tested, relationships/associations included. Now you want to find out how to avoid testing Rails logic, and instead just test that the relation was setup, but that's not tough to do.
Minitest suites I contribute to all have tests for the existence of expected relationships/associations.
Again, the idea is that if someone accidentally removes or adds a character or two to that line of code, there is a specific test to catch it. Not only that, but removing the line of code deliberately should also include removing a test deliberately.
Yes of course if someone wants to remove that line of code completely, and go remove a test, they should be able to do that. And at that point the assumption is that the entire task was deliberate. So that's not an argument to avoid testing in my opinion. The test is there to catch accidental mistakes, not deliberate actions.
Additionally, just because the test seems like copy/paste or repetition, that's also not a reason to avoid it in my opinion. The better the application code is, the more all tests will start to look repetitive or like copy/paste boilerplate. That's actually a good thing. It means the application code does just one small thing (and likely does it well). The more repetitive tests get, the easier they are to write, the more likely they are to be written, and the more you can refactor, simplify, and DRY them up as well.
In my opinion, this should be a best practice and I've not had much push-back from any of about a dozen other Rails developers I've worked with personally. And on a wider scale, the fact that shoulda-matchers have specific matchers for this means there are enough other developers out there wanting this capability.
Here is a minitest example of testing a relationship/association without testing Rails logic itself:
test 'contains a belongs_to relationship to some models' do
expected = [:owner, :make].sort
actual = Car.reflect_on_all_associations(:belongs_to).map(&:name).sort
assert_equal(expected, actual)
end
To your point of the fact that it doesn't test the actual behavior of the code, and only tests that the relationship was defined when you'd expect a method written on a model to test the actual behavior of the method itself, not just that is was defined...
That's because you as an end-developer wrote that model method, so its behavior should be tested. But you do not want to test logic existing in the Rails core, as the Rails team has already written the tests for that.
Said another way, it makes perfect sense not to test the functionality of the association, but only test that it is defined, because the functionality is tested already by the Rails test suite.
In our company we don't test Rails internal logic.
We don't check that Rails handle has_many, belongs_to etc. correctly.
Thats Rails intern stuff you shouldn't have to bother about.
Normally you have more than enough other stuff to test.

The "Right" flow in creating a Rails project

I'm starting out with Ruby on Rails and I know of a few stuff already, but I was wondering if there was a "right" way of going about developing a project. Right now, I would create my models first using [script/generate model MyModel] then modifying them until I feel they are complete enough. Then I'd go for [script/generate scaffold MyModel] so I don't need to do as much coding for the views. Lastly I modify the views and add more models then scaffold some more for other features I might need.
Would there be a better way of doing this? Especially in the context of working with a team in developing a project? Thanks!
I'm sure everyone has their own workflow, but I think a typical one is this:
Specify the "domain" your project. This probably sounds silly, but before you get started you should really think about what exactly your website is going to offer. It doesn't need to be specific down to the last detail, but should have an idea so that you can perform the next step...
Design your database schema. I usually just plan this out on paper. There's a real art to creating a normalized database. Think of everything that needs to be "permanent" in your app, because it will have to be in the database and accounted for, with as little duplication as possible.
After this I usually do as you say: create my models (and migration scripts along the way). The main thing you want to get down in your models first is the associations with other models.
The next part depends on how comfortable you are as a developer in Rails. A lot of people enjoy the test driven development approach (TDD), and will write Unit tests (Rails provides excellent facilities for writing these, and rake tasks to run them). However, since you're just learning, you may want to write your tests after you implement your model business logic.
The road after this is pretty much up to you. You can work on your views/controllers/models as you need to. That's one of the beauties of Rails and agile development, you don't need a lot of boiler plate code to get started.
I'm probably weird in this, but I usually design my front page and get some basic CSS going, as I find I am more productive if my results are semi-nice looking.
I would probably avoid generating scaffolds though...I think you'll learn a lot more about the framework and spend less time removing unwanted code if you generate the individual pieces themselves.
In the context of developing with a team, things will probably be different. If you have a lot of complex business logic, some people may spend most of their time writing model code, while people more on the design side will be implementing view code. But you will have to meet in the middle of course, which will get easier as your project grows and becomes more modular. Just remember to use a version control system! Subversion if you want something easy to use and learn, Git if you're up for a challenge.

Advice/tools for working on a large existing rails application? [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 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.

Your thoughts on using Rails scaffold generators

I'm attempting to learn Ruby on Rails. I'm pretty confident with the basics and writing my own models, controllers and views, although I only know the basics.
Lately I've found that, when I start a new application, most of my models nicely fit into the REST philosophy, and I end up just writing most of the same scaffold-generated code by hand anyways. In a case like this, do you think it would be acceptable to start from using script/generate scaffold for each of my required models, and then modifying code as necessary? The prevailing opinion that I've seen seems to be that the scaffolding is a "newbie trick" and real developers don't use it, but for most applications it seems to create a fair chunk of usable code (as opposed to bad code).
What are your thoughts?
I'm not sure if the culture is really against scaffolding or not, but I, for one, love it.
Now, what I do know is that there was sort of a small backlash against scaffolding for a while. This was because basically every Rails tutorial was basically 'whoa, just type
ruby script/generate scaffolding Post title:string body:text
and you have a blog! Done!'
This not actually being the case, the community started to pull back on using scaffolding as that kind of example, because when you do this, you're not done.
The real power of scaffolding, and the reason that I love it, is for its rapid prototyping abilities. You can generate half of your web site, start coding the back end, and still have a usable interface to actually play around with how everything works without worrying about writing interface code.
I think the idea is that you use it to generate 'generic' code, and then rewrite/refactor it to your specific requirements.
I think there is no problem using the code out of the box generator if it does what you want - as long as you remember what it all does from a security point of view (e.g. don't leave in edit/update/destroy actions if you don't want your interface to allow this)
One thing I like, to avoid lots of duplicate generated code, is the make_resourceful plug in - it abstracts the duplicate default code and lets you override it as appropriate.
Rails' fanatical devotion to choosing smart defaults is exactly why you observe that when you hand write code it ends up looking like the code generated by scaffolding. Personally I really enjoy using scaffolds because there's only a couple of tweaks needed at the end (layouts, CSS, validations, etc etc) for those really basic CRUD type operations.
Even when you get to things that are more complex, it's easy to start from a scaffold and move towards what you want. Definitely not just a newbie's tool.
It is a myth that scaffold is meant only for newbies. It is a great tool to kick start you application really quickly. Of course you will need to modify the generated code to suit your requirements. Having said that, it never hurts to have a ready -made code, most of which will be used as is.

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