Refactor ruby on rails - ruby-on-rails

What is best way to refactor in Ruby on Rails. I have a project where i would like to refactor several of my objects - extra properties and renaming of existing properties. How do i do this this the easiest way?? I created the different objects with scaffolding "rails generate scaffold foo name:string...."
I do start from scratch or is there some cool ruby command, like "rails refactor foo name:string"..

As far as I am aware, there is no automated way to do this. The key things as far as I'm concerned is to make sure that your test coverage is good in the relevant area (and preferably across your whole app) before you start.
Once that's done, I've tended to apply fairly brute force tactics to do that actual refactor:
Run all tests.
Searching for relevant file names and strings within files, making a value judgement as to whether you're changing the right thing (don't just do search/replace).
Refactor your tests along side the code itself.
Run all tests again.
Repeat until it works.
The reason that refactoring isn't very automated in Ruby (in my view at least) is because the language is so dynamic, so it's very hard for any automated tools to make sure they've covered all the bases.

Refactoring is based on human perception. Sure, omission of some redundant things could be figured out by a computer, but otherwise when you refactor you're essentially improving your own hand-written code. Unless a computer has the intelligence and the ability to discern code like a human, then no, it's not possible.
Perhaps you're referring to something else?

You should learn some Rails best practices and use them to refactor your code

Firstly a good knowledge of your application and then start in a procedure and serialize it.
Use helpers to optimize.Methods should be small enough and minimize the possiblity of repetition of codes.
Use application files which helps a lot
You can also write methods in private to reduce the lines in methods.
Alwayz be sure where refactoring is done and its dependencies..
Thanx
.

Related

Ruby on rails development flow/order

Now that college is out for the summer and my classes have come to an end I need to be able to keep my mind sharp over the summer. I've decided to try my hand at making a nice enough ruby on rails app from start to finish.
I've tried doing this before but the problem I always run into is:
"I can't really finish this until that's done but it seems like it won't work unless I finish this other thing that need the first thing to work."
Basically my project gets out of hand really fast because I have no direction regarding what to work on and when.
My question to you, oh great and wise community of SO, is what is the most accepted way to go about developing a rails app.
Do I start with models, views, or controllers?
Is it better to make the HTML first or the server code?
What is the best way to get things done?
Thanks in advance!
The Rails community strongly promotes some form of test driven development. When you're just getting started, it probably doesn't make sense to start out writing tests, but you can still keep the same approach.
So, essentially you would just try to do what you want in the browser and write what you need as you need it to accomplish that.
So getting started, just generate a new rails app and start the server. It will give you the default Rails environment information. You don't want that to be the home page, so you go to the routes.rb file and define your root address (e.g. root 'welcome#index').
Now you reload the page you get the error "Uninitialized constant WelcomeController'. So now you need a controller. Add the controller.
Now you get an error 'The action 'index' could not be found for WelcomeController'. Define the index action on your WelcomeController.
Now you get the error 'Missing template welcome/index'. Add your views/welcome/index.html.erb view.
etc. etc.
Soon you'll find yourself needing models. Reference the model as you'd like to interact with it from the view. e.g. #articles.each do |article| etc.You'll get an 'undefined method on nil' or similar.
Then you define your model as you'd like to intereact with it in your controller (e.g. #articles = Article.all). Then you'll get an error that your model doesn't exist. Create the model.
Add the attributes to the model that you need in the view.
Repeat the process...
Design
Decide which features you are going to implement
Decide which gems you are going to use to implement those features
Configure and implement those gems/features in isolation - Use Git
Realize that you are spending a lot of time here.
Consider trimming the features or simplifying the design. Maybe go back to the top.
Start coding your master app - Use Git
Configure those gems together - Use Git
Write the Models - Use Git
Try to write controllers and views(Use scaffolding to get started, that way you'll be doing more hacking and less coding) - Use Git
Run into a problem in last three steps, or discover a new feature that you must implement to make everything work.
Solve that problem in isolation (in a separate rails app) - Definitely Use Git
Repeat
About Using Git
Damien Roche has suggested in the comments to use Git branches instead of testing new tools in isolation.
I have been using Git with Rails from the beginning, and I recommend using Git branches and testing new tools in isolation.
e.g.: You can see a public Github repository of mine here: https://github.com/spundun/emblem-coffee-emberjs-rails-starter-kit . It's a simple single branch repository where I document each step I'm taking to incrementally shape my project.
But when using a new tool or library, many times things will break, and you will start with no clue as to why things don't work the way they say it will, in the tutorial. Did I use the wrong version of the library? wrong version of Rails? Did I add tools in the wrong order?
To make sense of such problems, many times you'll want to compare a working directory that works with working directory that doesn't. Meaning you will want to have two working directories side-by-side.
Of course you can achieve the above by cloning one directory into the other and checking out two different branches, but we are getting ahead of ourselves. Before making a gem co-exist with a dozen other gems that you are using, you should make sure that you know how to get it to work in the simplest of the scenarios. Meaning with vanilla rails, with the bare minimum that is required.
So first you will make this isolated branch incorporating the new gem into a vanilla rails app. This branch is not related to your main branch in anyway, except it should use the same version of rails that you are using for your app. You can host it in the same repository or a separate repository, really doesn't matter.
Once you feel confident that you know how it's supposed to work in isolation, you can trace all the steps you took using the commit log of that isolated branch and incorporate those commits as appropriate in a feature branch on top of your master branch. And when you are done fixing bugs and making all the gems work in harmony, your feature branch is ready to be pulled into the master branch.
HTH.
I think it's a good question and I expect to see some insightful answers here.
In my opinion it's something that comes with practice, and you will constantly switch between M, V and C. I think the Model is usually the first part to implement, as it is often determined by the real world problem domain and therefore less fluid and subjective. Then the Controller and the View next. If you just implement the smallest working part with each iteration you get to see results sooner and it helps for not getting bogged down. (Although I like to try and define all fields in my model up front).
But really the best way to not get lost is step back and take pen and paper and sketch out the main workflow and entities in your system, in whatever notation works for you. Keep it simple so that you can visualise the main stuff your system does end to end, on just a page or two. Then when you're implementing, those designs can serve as a map for where you are in your build.
Of course you could also try to specify system tests up front (or rspec feature specs) to define what the system should do. This has never worked for me to be honest.
Many software development methodologies exist and continue to evolve albeit at a slower rate than the programming languages they implement. I'd recommend researching the Agile Manifesto and memorizing it's principles.
My typical Rails application workflow:
Write and implement a feature (Cucumber).
Write and implement a spec (RSpec).
Write a benchmark and refactor.

Rails: where to put statistics code?

I have a Rails app that uses a lot of custom statistics code I wrote, things like calculating the mean and standard deviation of an array of numbers, or calculating statistical significance tests.
Where do I put all this code? It's not tied to any database object, so I'm guessing it shouldn't go into /models. And if I understand correctly, /app/helpers is only for helper functions called from your views, so I don't think it should go there. Am I supposed to put my statistics code into /lib?
In general, I'm not sure where I'm supposed to put helper libraries that are called from my models.
As an aside, you can definitely have models that aren't tied to database tables, but they should still be classes that represent "things" in your domain, in my opinion. So I still wouldn't put them in /models, but not because of anything to do with the database.
I would put them in /lib, yes. Note that they won't be loaded by Rails automatically, so you'll want to add require statements in an initializer.
If this code is only useful for this project, then /lib is a good place. However, you might also consider packaging it into a gem if you think you might use the code in another project later on, especially if you're going to have more than one project using this code at the same time.
/lib sounds good for these stuffs
Agreed, putting your code into a module that can be included into your models is the way to go. That usually goes into lib/

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.

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