Related
There is a production system that has been running for many years, first as a PHP application, then as a hybrid with Rails, and now completely in Rails. It's unclear how long it has been around. The oldest git commit is from 5 years ago.
The goal is to keep the system running at all costs. It doesn't matter what code we use as long as nothing breaks. Currently it's at Rails version 3.2.33.
If we don't upgrade any gems we run the chance of becoming obsolete and undeployable. If we upgrade we will need to make changes to the code causing potential bugs to creep in. Not only do we face code rot, but also downtime due to AWS outages.
What would be the first step to make sure nothing breaks? I've spent months writing cucumber (integration) tests but it's hard to cover every edge case. The app has been running so long that most bugs have been fixed and there are few new exceptions. Testing was not a priority from the beginning so most of the code is undocumented.
Honestly, I find that Ruby on Rails is not ideal for this sort of application. Both Ruby and Rails have a very aggressive release schedule, and Rails especially isn't afraid to ditch backwards compatibility. Rails is great for agile development where things are always changing, but at the cost of long-term stability.
I'm assuming your application is big enough that you don't want to switch to anything else. Sinatra, for instance, doesn't change much and would be a much more stable option.
If you're sticking with Rails, I'd recommend getting rid of as many gem dependencies as possible. There is always a danger that they will no longer be developed or that they could introduce bugs or vulnerabilities.
Also, as much as possible, it's a good idea to favor POROs (plain old Ruby objects) over Rails dependent code. It generally takes more work but you wind up with more stable and reusable code.
I realize that may be more work than you want to put into an application like this, but that's my best advice.
The first step would be to put specific gem version for all gems used in the gem file.
For exmaple
gem 'rspec-rails'
might become
gem 'rspec-rails', '2.14.1'
You can figure out which versions are currently being used by looking at your Gemfile.lock, for example, this line in Gemfile.lock shows the version selected for rspec:
rspec (2.14.1)
and even if the Gemfile has no version, e.g.
gem chronic
the Gemfile will have the version used, e.g.
chronic (0.10.2)
If we don't upgrade any gems we run the chance of becoming obsolete and undeployable. If we upgrade we will need to make changes to the code causing potential bugs to creep in.
Yes, that's your dilemma. There isn't any magic, you have to pick which of these two priorities you want to address. As aNoble indicates, RoR is not a framework that can 'stay in place'. constant change of the gems that combine to make up most applications means that RoR applications do not age well.
You should explain and repeat, repeat, repeat this to the project owner. Frequently this is the kind of principle that is "accepted" - but not really - as the same questions continue to be asked "despite that, how can I upgrade it, how can I make sure nothing changes or breaks, etc."
If the application will be retired in a couple of months, no problem. If there is no real plan to sunset the application and it will continue to be an important part of the business then you just have to use resources to maintain it. no free lunch in RoR land.
Writing many tests is a key first step, glad to see that. Check your statement coverage to see if you're missing tests of important areas of code, and be sure that you have integration tests that cover the key sequences. The idea is to modify your tests to reduce the risk that a change will cause a user-visible failure.
Now setup continuous testing on some system.
Set your Gemfile and .ruby-version so that you have specific control over exactly what versions of everything gets loaded. That doesn't automatically update - but it ensures that you have control over what you update. Check in both Gemfile and Gemfile.lock.
At this point you can slowly increase version numbers. Don't jump lots of version numbers - it's typically better to upgrade slowly so that you can see deprecation warnings. Fix those, rinse, repeat.
Modify your (input) validators to be picky whitelists ("it must be of this form or I won't accept it"). If you can prevent bad data from entering your system, it's more likely to work correctly and will typically be harder to attack.
For security, consider adding secureheaders, and set CSP as strong as you can stand.
Start adding some static analyzers. Rubocop and Brakeman are very useful. You'll probably have to configure Rubocop to only complain about a few things, and then slowly increase what they report. Add all your checks to the default "rake" command, so that you can just type "rake" to run static analyzers and the test suite.
There's no magic, regardless of what framework you use. People make mistakes, and pretending otherwise isn't helpful.
You might the CII Best Practices badge project a useful example. It uses RoR, and I lead that. In particular, see:
* CONTRIBUTING
* Security information (assurance case)
From CONTRIBUTING:
"In general we try to be proactive to detect and eliminate mistakes and vulnerabilities as soon as possible, and to reduce their impact when they do happen. We use a defensive design and coding style to reduce the likelihood of mistakes, a variety of tools that try to detect mistakes early, and an automatic test suite with significant coverage."
I'm new to Ruby on Rails and have been seeing people use auto boilerplate generators like Rails Brick or Rails Composer to create boilerplate user-management systems, etc. Coming from a background that doesn't trust auto-generated code, is it good/legitimate practice in Rails to use such systems. Also, I'm working on a project with a startup. Is it fine to use such generators and how widespread a habit is this.
P.S. Mods please note that this is not a question asking comparisons/opinions/disputes. I'm curious about the general practice in Rails and how often is this used in production.
I'm the maintainer of Rails Composer so I believe I can answer this question with authority.
I respect (and share) the urge to build from scratch. That's a healthy impulse. Rails includes a facility for application templates (Rails Composer is an application template) because automation saves time and effort. For people who build many web apps, a time comes when you decide to automate the process.
Rails Composer offers an advantage over roll-your-own application templates because it is open source, used by thousands of developers with code contributions by many. As Rails and gems change, Rails Composer gets updated so you get a current "reference implementation" every time. It gives you well-tested starter apps that integrate all the bits and pieces that require tweaking, like RSpec plus Capybara and FactoryGirl, flash messages and navigation with either Bootstrap or Foundation front-end frameworks, Devise or OmniAuth for authentication, Pundit for authorization, and many utility gems that developers like to add (Guard, Pry, etc.). It lets you choose your stack (for example, ERB, Haml, or Slim), offering choices to the extent that the community has contributed options.
If you're concerned about the safety of running an install script, the code is open source and used by thousands of Rails developers (you can see over 2000 watchers on the GitHub repo). It's purely an application template using the Thor library, and though in theory someone could contribute code that tampered with your files, we'd never accept a pull request like that. Rails Composer only offers well-known popular gems, so you are not exposed to potential risk of using unknown gems.
Rails Composer is widely used, particularly by consultants who build lots of apps. Many of the prominent consulting firms have an in-house application template (Thoughbot Suspenders, for example) and some use Rails Composer or the rails_apps_composer gem that generates custom application templates. Developers who work on on only one application regularly (maintaining a big project, for example) tend to be less familiar with application templates like Rails Composer, but it is popular with developers who start a lot of apps.
Stack Overflow is not a place for opinions, so if you want a range of opinions or debate about the merits of Rails application templates, Reddit or Quora might be a better place to ask.
Welcome to Stack Overflow! I hope all your questions will be answered accurately and timely.
I'm the developer of Prelang which is similar to the generators you mentioned. It differs by adding data modeling, GitHub integration, and deeper configuration for some features. Like Daniel, I believe I too have some authority on this and agree with his very complete answer.
To answer your question, Prelang is newer but it's already used by thousands of developers ranging from beginners to dev shops.
I'd like to note that Prelang (and the other builders) are different than what you traditionally think of when you hear "code generation". When working on Prelang, my goal is to automate "everything that a Rails developer would have done anyways". Prelang does generate methods/code but mostly it's automating install processes of Gems, setting configuration values, creating models, and running rails commands. That said, Prelang is opinionated in terms of which gems it uses but I've selected the most popular gems for each feature and will give the flexibility to choose between multiple routes once I get a little more traction.
Prelang also makes real Git commits so you can look through every commit after your project generates giving you full visibility into your codebase. This is intended to further ease concerns relating to generated code.
Erik
Most gems are so easy to set up nowadays, that I think you won't need such a generator. After all it's just a question of taste – I like using the command line, and I like knowing exactly what's in my codebase. From my personal experience, I have never seen someone use such a thing in professional Rails development, but clearly there are people out there who use them.
The one case I can think of where these generators make sense is when you're bootstrapping projects very frequently. In this case however, I find the existing generators not to be flexible enough. Thoughtbot for example has built their own app generator called Suspenders, which of course includes a very opinionated set of gems etc. but it gives them exactly what they need.
As a side note regarding your security concerns: for me, the dependency trees that are spanned up when you use many gems are a far worse security threat. For example in a medium sized Rails project it is not uncommon to depend on 100+ Gems; no-one can read all of them. You'll have to trust all of those as well.
I am a beginner-verging-on-intermediate rails developer that is working hard to improve my skills.
I am a little confused about the state of JRuby, and whether it is a viable alternative to switch to from the MRI.
Currently I run a Mac at home and edit using textedit (MRI for ruby, terminal for rails commands, etc). At work, I use NetBeans on Windows, but don't do any Ruby work there.
I am seriously considering ditching the Mac for reasons irrelevant to this conversation, but I am worried that once I am on Windows, the support for Ruby will be less-than-optimal (I may be wrong about this).
I really enjoy working with Netbeans at work, and I can see that using JRuby on Windows with Netbeans and allowing JRuby to manage my gems would be a relatively pleasant experience. I like the idea of code completion and a full IDE rather than a text editor (without starting an editor flame war).
My question is, is JRuby going to complicate learning rails? From what I have seen, certain gems aren't supported on JRuby, or things might be done a little differently in that ecosystem. As a learner, I follow a lot of tutorials from the web and from books and I am worried that things might not work or will be hard to get working on JRuby. Is this scepticism well founded? Or should it be a relatively painless switch? How does it effect deployment onto non-JRuby platforms such as Heroku etc?
I am still weighing up a lot of options including MRI on Windows, MRI or JRuby on OpenSolaris, etc. I think that either way I will be going with Netbeans.
Any comments are appreciated.
Realistically you don't need code completion for Rails. TextMate is by far the most commonly used editor in the Ruby world, and it's more than sufficient for everything in Ruby. Ruby doesn't require anywhere near as much tool support as Java. So I would say that if the editor issue is the only reason you're opting for JRuby, it's not a very good reason. Because you're right, there are lots of gems that don't work in JRuby because they use a native extension of some kind. That said, the most popular gems tend to work in JRuby. Performance in JRuby still isn't quite as good as Ruby 1.9, but in a lot of cases it's comparable to MRI 1.8. Personally, I'd recommend treating JRuby as an advanced Ruby concept. It will run Rails, but yes, you're going to find that you won't be able to just follow along with a tutorial, and everything will be ever-so-slightly harder for a beginner. JRuby isn't a particular daunting piece of technology, but it might be more of a hurdle than you want to overcome as a beginner.
I highly recommend shelling out the Euros for a copy of TextMate anyways, even if you don't do your development in it primarily. It's worth every penny and then some. Work in that environment for awhile and see if you really need your IDE. I'm betting you won't.
My question is, is JRuby going to
complicate learning rails?
Yes, because all the tutorials, beginner docs, and most of the devs who will normally be able to help you out are assuming MRI, so for each issue you have you must first eliminate a jRuby related cause.
From what I have seen, certain gems
aren't supported on JRuby, or things
might be done a little differently in
that ecosystem.
Any gems that are written with C native extensions need to be ported to jRuby (the inverse is also true, but the issue is rarer).
As a learner, I follow a lot of
tutorials from the web and from books
and I am worried that things might not
work or will be hard to get working on
JRuby. Is this scepticism well
founded?
I'd say yes, see my first point.
How does it effect deployment onto
non-JRuby platforms such as Heroku
etc?
The more your development environment strays from your production environment the more 'wacky' bugs will turn up. The alternative is to deploy to google app engine using jRuby.
On the other hand, who will write the jRuby tutorials if there is no demand?
I use Netbeans, Textmate, and Vim, but usually Netbeans. I love Netbeans's integrated debugging it is very helpful at times. Netbeans and Vim are cross platform and that is a big deal to me. I hate being dependent on software that is only available for one OS. I'm pretty sure I have tried just about every IDE for Rails, and Netbeans is the best Rails IDE in my oppionion, but I digress.
cwninja is right about JRuby's gem incompatibilities, albeit most gems are supported with JRuby. See http://isitjruby.com/ for supported gems. JRuby has a lot of momentum right now and is a strong development choice. In theory, choosing JRuby, or MRI should be inconsequential, but don't hold me to that. JRuby does allow to easily switch ruby compatibility between 1.8.x and 1.9.x pretty easily, but then again you could use RVM (which happens to be the bomb) to achieve this.
Either way, if you are considering using different ruby interpreters, take a look at RVM. It allows you to easily install and manage most ruby interpreters easily.
Look TBH moving away from a UNIX system towards a Windows system for Ruby developement, well it just seems stupid. Don't use a Mac if you don't want to, but a lot of stuff on Windows will just not work very well. You will spend more time screwing with stuff to get it working, than doing any work.
I recommend not using a code completing editor, it doesn't help you learn. I would say stay away from that till you have a good grounding in the language, learn where to look things up APIs etc before you start trying to shortcut things.
JRuby is definately a good alternative to MRI ruby, but if you are following tutorials it may just add the level of WTF as you learn that may well be counter productive, but if you do go to windows JRuby is probably the best way to go.
Good luck.
I started with MRI on OS X and then Windows. I use JRuby on Windows currently, but still fall back to MRI on Windows to check behavior, which is something you'll get used to. JRuby is undergoing a lot of changes to get it compatible with Ruby 1.9 and Ruby itself is somewhat of a moving target.
Looking at the differences between the two and reporting bugs though will ultimately strengthen your understanding of both, and will help both teams push the language forward.
I would like to use a lighter framework than Rails (Sinatra/Ramaze/Camping) but am concerned that by doing so I will not be able to use a lot of shared libraries that have been tailored to Rails in the form of plugins. Is this a major concern or are most of these plugins usable across different Ruby frameworks?
Are there any other potential disadvantages in using a Ruby framework other than Rails?
You can still use gems in all of the frameworks you mentioned, so a ton of stuff is reusable. Want to swap in a new ORM, no problems. Want a fancy shmacy syntax highlighting, no problems. Rails has been making a huge push to move away from the old plugin model to use gems exclusively.
If one of the other frameworks fits your needs better use it. Keep in mind that when it comes to documentation and samples rails has more.
If I was learning Ruby and wanted to try out a web framework I would probably go with Rails not because its better, but because its got much better tooling and documentation.
Most Ruby modules used by Rails (even ActiveRecord) can be used without Rails. But then you lose the extra benefit of integration provided by Rails. You may have to work extra hard to glue Ruby modules to the framework of your choice. Please also note that most of the documentation about Ruby modules used by Rails tells you only how to use that module with Rails.
Network effects play a bit of a role.
One issue that comes up when you use other frameworks like sinatra, camping, etc is that rails gives you a proven structure for your files in the your application. Smaller frameworks are quite open and free.
This can be a downside when you are working with multiple developers as you need to have conversations about creating conventions rather then simply following them.
If you've been using Ruby for less than a year, stick to Rails, unless you have a very clear need that is better handled by one of the other frameworks.
The lighter frameworks, most notably Sinatra, tend to be popular with people who know exactly what they will need and can't afford to have any additional overhead from unused code. Essentially, you pick your toolchain, instead of generally being stuck with what Rails gives you. (Yes, in Rails, you can replace ActiveRecord, et al. with other libraries, but it's not exactly easy.) So the lighter frameworks give you significantly more freedom, but you also have quite a bit more work to do in many cases.
I think no rails plugin is going to work out of the box with any of the alternative frameworks, except for ActiveRecord plugins (such as acts_as_nested_set etc.) which are still going to need some plumbing work (setting $LOAD_PATH and requiring right files). I'd recommend DataMapper for ORM, not only it's way faster than ActiveRecord, but it's also very modularly built and plugins are actual gems that you can easily install. In difference, ActiveRecord plugins are mostly monkey-patches that tend to break with every new version.
Sinatra doesn't come with any "goodies", no Rakefiles, no skeletons, no script/generate, but actually that's what it's been written for. You can gradually "plumb in" all the extra stuff. There are also skeletons for sinatra apps that come with some basic layout and defaults, you may find these useful.
I'd like to know situations in which I should consider using a framework other than Rails.
Two things. First, Ruby is a relatively young language, and you may run into brick walls when trying to do slightly more esoteric things (like connect to non mainstream or older types of datasources). It also has poor GC, and no kernel threads, both of which are very important for a high performance platform. The main codebase (MRI) is quite hacky (lots of clever obfuscating programmer tricks like macros) and there are parts that are poorly written (gc and thread scheduling leap to mind). Again, it is a very young platform that got very popular very fast.
Secondly, while ruby the language and rails the ideas/paradigm are both phenomenal, ruby and rails the platforms are not. There is a hell of alot in both ruby and rails that is downright ugly, and deployment solutions are in the dark ages compared to what is considered normal for other platforms (php/asp/jsp).
Being accused of trolling here, so I will expound a bit. Due to the threading model, Rails cannot process requests concurrently unless you launch multiple full instances of your rails app. To do that you have two options, the relatively young and still under development passenger (mod_rails), or the tried and tested apache load balancer with multiple mongrel instances behind it.
Either way, the lack of the ability to just just spawn workers means you will want 5-10 full instances of your application running, which incurs a very large overhead (can easily be 300-500megs per app depending on your gems and how big your app is). Because of that, the infrastructure needed to serve rails is a hell of alot more complecated then most other things.
Now, that being said, the situation has been continuously getting better (I mean, passenger is usable now, it wasn't the last time I had to deal with deploying a rails app). I would be very surprised if rails doesn't catch up in the next few years.
Also, rubinius/jruby are doing things the right way, and are moving along at a great pace. I wouldn't be suprised if MRI gets dropped in the next few years in favor of one of those implementations for mainstream rails work.
Ruby on Rails isn't trying to be an end-all be-all web development framework. If you're going to build an application that is predominantly built using CRUD operations, you want to use a lot of AJAX, and you have total control over the database, then Ruby on Rails is one of a few excellent options. If you're doing something else, then there is a probably another framework that is a better match for your requirements.
edit: Matt amended his answer tastefully :) I've removed my own comments pointing out the things he's fixed.
Yes, Ruby definitely has some shortcomings. Green threads being a huge one. But as Matt has said, things are moving along in better directions.
The other posts are pretty much on the money. Decently simple CRUD apps are best suited for rails, though there are other frameworks you can try in Ruby that offer more flexibility.
Here's a great (and might I add objective) example of where not to use rails: Does the Rails ORM limit the ability to perform aggregations?
Wow, way to start a flamewar!
I'm going to start it off by saying that Rails will work for most apps. However, if you need to do a lot of async type work (like messaging between systems, such as getting a request, placing it in a queue and processing it in a different thread, or even on another machine), Rails is probably not your best choice. Ruby, at least at the current time, is not really strong on multithreaded code.
Let the insults fly!