Revert the results of rails scaffolding in production - ruby-on-rails

When a model is generated in rails - let's say to keep records for users, then we also get a route/controller/view for handling these (CRUD). Therefore visiting "root_url/users" would list all the users, "root_url/users/1" would display the first user etc.
While this is handy in a dev environment, it's not inappropriate for production (currently production for me is Heroku).
I could just remove the extra controllers, views etc. but I was wondering whether there is a standard way of approaching this issue (like a flag in a config file) so that there isn't a mismatch between dev and production.

Yes there is a standard way of approaching this issue, it's called testing, code review, and generellay just doing what is required for your application to work.
Scaffolding code is a good thing, but you just have to use it when it's needed. If you commit often enough, you can scaffold and easily reset what you've done if it does not meet your need.
It is your responsibility to not put any code in production :)

Related

Ruby on Rails database workflow

I'm a bit of a Rails beginner, so I'm sorry if this question is easy. I'm wondering how I am supposed to modify the Rails database as a developer without letting users of the site modify data.
More information:
Let's say I am trying to create a website that lists books along with their information. I want users to be able to see these books, but not add/delete them. As a developer, I want a way to add books without using the command line (hard to edit mistakes). What's the easiest way for me to do this? Would there be any differences between the development database and a live hosted one?
I think there are a few approaches to do this.
different user roles. This technically breaks the rule of without letting users of the site modify data, but being able to differentiate between normal and admin users means you can limit who actually can add data into the database. I used cancancan as a way to authorize requests but I know there are others.
I agree doing it using the command line isn't ideal, but rails do support rake tasks. You can create a task that will handle most of the logic and all you need to do is something like
rake create_book["name here"]
This will make the process less error-prone.
Create data using rails migrations. Rails can generate the skeleton file for you, and you just ran any ActiveRecord methods. However, the main purpose of migration is to update the database schema, but they can seed the database as well. here's the example from the dcos
Would there be any differences between the development database and a live-hosted one?
Yea, they should be totally separate database instances. You don't want to have your development database be the same as the live one. This would cause major problems. Rails have a concept of environments where you can use different configurations, so you can pick and choose what database URL to use.
like #davidhu said here The best approach really is the use of authorization. If only admin can see a page to CRUD the books then you don't have to worry about normal users doing same plus it makes it easy for you as the admin to make changes or add to the collection. Add the gem (or reinvent the wheel) then Rails will take care of the rest for you.

What are the steps for modifying an existing rails application

I am new to ruby on rails and I am working on a web application written by ruby on rails. It has more than 10 models and I need to add some new attributes to some of the models as well as new methods and views. I also will need to remove or enhance some of the functionality. I know that I would need to generate new migrations and from there add/remove new columns. Then in controllers, add/modify methods, and update the views.
I wanted to know what would be the best steps (and in which order) for doing the above tasks. Also, do I need to change other files in folders like test or any other folder? What things should I consider to minimize the troubles later?
Thanks in Advance.
Since you are new to rails, the first thing you should do is to read through the getting started guide. This will help you understand the fundamentals of the rails framework and the application you inherited. After that, there are several other guides worth reading (from the same site) that may be directly applicable to the work you are doing.
Another incredibly helpful resource is railscasts. Some of these are outdated, but they are still a great starting place and can help introduce you to both new, powerful gems and rails techniques to get the work done faster and better.
As to your specific question, rails is built on an MVC architecture (meaning Model Views Controllers). It is in your best interest to try and follow this practice whenever possible. Reading up on this will clarify some of your questions as well.
When you run a migration, you will be modifying your database. The changes are viewable in the database schema (which should never be modified by hand, always modify it through migrations). This will add attributes to your models whose table you modified. In the controllers, you will add logic to deal with all of these things and the views will present the data to your users (or allow users to enter data). Asking which order is best is probably rather opinion based, but I would say you should modify the tables (run needed migrations) first. This way you can then generate the logic to deal with the new attributes. I would then create the controller logic and finally the views.
You also ask what other files need to be changed. This is heavily dependent on your system. At a base level, you should definitely be writing tests to support the logic you are generating (and many developers will advocate that you should do this before you write the other logic, a process called Test Driven Development).
TL;DR: Read the guides, work through a basic tutorial, and watch some Railscasts. This should get you up to speed on the process and best practices that go along with rails development.

Pushing CMS/static content from staging to production database?

Most Rails database-deployment discussions assume there are two facets of a database: the schema, which is handled in code via migrations, and the data, which is all user-generated and never needs to move from test to production. What about the stuff that lies in between?
For example, we have a number of mostly-static tables that contain complex surveys our users can take: questions, choices, branching. We want to be able to edit those surveys via our web app, but we want to be able to test changes on the staging server before we push them to production.
What's a good way to handle this in Rails, which wants all the models to exist in one database, and certainly wouldn't like the same model (with different contents) to exist in two databases? Are there any good discussions online, or any gems that have abstracted out this type of functionality?
I've worked with a large, complex CMS system that had its own multi-environment version control and deployment, so you could deploy your change to the test system (without riskily linking the test and production databases), test it thoroughly, and then do a one-click deploy to production. I guess I'm looking for something like that on a smaller scale.
I would use ActiveResource to pull the desired records from the staging environment to production. Alternatively, you could create a name-spaced set of ActiveRecord models to connect to the staging database directly. Either way, the implementation is roughly the same, but ActiveResource allows more flexibility with changing deployment details and the ActiveRecord method requires less setup code.
The actual implementation code should be fairly simple - pull a list of un-imported records from staging (you'll probably want to map the production records to their source staging records to easily prevent duplication) and copy the data.
Not sure about Rails but I am using one python script called Migraine, its useful to synchronizing development, staging, and live (production) sites' databases for Drupal CMS. For more info refer this :
Presentation
Get Migraine script here

How do I offer a beta feature to select users? (rails)

We want to start letting our users help us test our feature changes before a wider release. Our rails app already has roles but I don't know how to we should go about implementing a beta feature without moving the whole app over.
Some issues I can't think of solutions to:
A beta feature may require a database migration. How can you handle this when it could cause problems with the existing app?
Changing templates and the css/sass will likely change it for existing features too.
Changing the underlying model code could break existing controllers / interfaces that rely on it.
One solution (a bad option) is to code in the new feature and wrap it in logic that only shows/uses it if the user has the "beta" role. The problem with this is when you finally take it live, you could have a lot of unwinding/changing to do. This is both a waste of time and could introduce bugs.
Another solution is to run a separate "beta" branch of the app off a subdomain and route users with the beta role to it. The problem with this is that the complexity of ssl certificates, email links and other domain dependent issues make this a bit of a maintenance pain (though not as bad as the first solution).
How can I offer this most efficiently so as to minimize the additional work to maintain and then switch the beta to the full version?
I think the only reasonable chance of these kind of tests work without affecting the current application would be using a "staging" environment and really just redirect the beta users to that environment.
Compared to problems with domain related features it is really nothing compared to migrations/functionality problems.
On our company we do exactly that, but we don't have the beta users thing, but without an separated environment it will be pretty much inviable to keep new features from messing with current features.
For the features, just use different branches for those new features and create that "staging" environment from that branch, once the features have been tested you just merge them to HEAD and new feature is there :]
One possibility to consider: making destructive (i.e. one-way, non-reversible) changes to your model may be problematic for reasons beyond inhibiting your ability to provide this beta functionality. For example, it may difficult to backout from a change if you have a problem during the migration.
Instead, I would recommend looking at ways to only add to the model: add columns while leaving old columns in place for backward compatibility, version stored procedures if you're using them, etc. If you need to alter column data types, instead create a new column of the target data type, then have your migration also copy existing rows data from the old column to the new column in the new format. You can then perform your database migration in your test environment and confirm that both the old and new versions of the application continue to work with the database changes.
One potential way to serve up multiple versions of your application is to use an alternative respond_to format for your beta site. You could create a method in your ApplicationController to check if the user was in the beta. If true, you can override the request.format value and in your respond_to block have a "format.beta" type response.
The challenge with this approach is the controller logic. Without embedding some kind of switching logic within your controller methods, you won't have a way of altering the controller code path. This may not be a major problem, depending on how many controller changes you have.
(By the way, it looks like we have very similar names! :-) )
What I can think of is something like having a user_type column in your users table. so that you can flag them as beta users. (Even you can set this flag as default so that you dont need to change the existing code. All the new users who are creating will be beta users.)
For this i'm assuming
You are giving all the features to your beta users
Beta users will be having the same functionality which will be having by normal user in future.
** Only advantage is that you can filter beta users as and when they are login. Upon that you can do something like allowing to login or not etc..
When you are switching to the full version just update beta users as normal users
I dont know how this is applicable to your scenario.
thanks
sameera
I personally don't think it's a bad idea to wrap the code with a check for a user having the beta role. It will be quite easy to search for all of the calls to, for example if current_user.authorized?(:beta) and the remove them entirely.
One thing I am thinking about doing is setting up a beta "staging" environment that is actually the production environment. The idea would be to have beta.mydomain.com and then send users there that want to get features early. Basically, it would just be a branch that gets deployed to the beta site which is live.

How best to cope with naming scheme changes in a Rails app

I look after an Rails app, that's about to have some key user facing parts renamed (like urls, and other such change like renaming 'blogs' to 'journals' and so on)
I'm slightly worried that over time, having loads of older names in the codebase for all the methods, routes and classnames is going to be difficult to read and maintain.
What's the best way to deal with changes like this?
And where are the gotchas like to be when aliasing methods and classnames, or running migrations here?
Thanks
If the app is development and hasn't yet gone into production you're safe to just go back and rename the migrations/models/views etc... and do a rake db:migrate:reset and be done with it. You should have enough tests to ensure that the rename didn't break anything, and if it does you should increase your test coverage in that area.
In so far as doing this for an app that is currently in production I suggest doing it incrementally so that the surface area for the change is reduced:
Change your routes
This is probably the biggest change. Updating your routes first will give you a chance to fix all of your views.
Update your models/controllers
You can do this without changing the database. You can make your model point to a new database table by using set_table_name "OldTable". This means you can make any database changes out of band of the release.
Change the database
Hopefully you're using a migration, in which case just do a table rename and remove the set_table_name.
I would rename the internal classes to match the external names, otherwise it just causes confusion when talking about the code. Sure, routing can make the external changes easy to switch, but there's nothing like reading in the code what you see on the webpage.
After the rename, I'd load the app up in a staging environment with the live data to test the migration, and then run something like tarantula ( http://github.com/relevance/tarantula ) to crawl your app looking for obvious broken issues that you & your tests may have missed.

Resources