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.
Related
I'm building a report app in Rails for a current desktop app. The app is kind of pos/accounting.
So at the moment there are different clients with the desktop app installed at shop or office. Each one has its own mysql database.
I am now planning how to setup the server, most probably heroku.
Given that I will keep the databases for each client separated, I'm trying to understand the best path to follow.
Another thing to consider is that there will be different version of the app, i.e. restaurant, bar, shop etc.. Different versions will use the same database. I'll just need to change some controller and view. Most probably I'll handle this using namespace.
For a client(company) multiple users will have access to the app.
The solution I thought is to create a database table company and add a column company to users table.
Things that could change from a client to another:
call different images from assets such as logo
there might be custom views or even controller if a client requests some customization
use different database
domain possibly, but that's not that important wouldn't a be a big deal to use the same
Then based on user.company show a different logo or any other required image, render a view instead of another, at login connect to the proper database.
I don't know yet how to implement it, right now I'm still evaluating the best approach to follow. But this way maintenance/updates would be easy to manage even if maybe performance will be a bit lower and code harder to understand with possible customizations all together but that's acceptable.
Is this a reasonable solution or should I consider something different? Am I missing something important to consider?
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 :)
Background:
We have app a, b, and plan to add more apps into this same application. The apps are similar enough they could share many views, assets, and actions. Currently a,b live in a single rails app(2.3.10). c will be similar enough that it could also be in this rails app.
The problem:
As we continue to add more apps to this one app, there's going to be too much case logic that the app will soon become a nightmare to maintain. There will also be potential namespace issues. However, the apps are very similar in function and layout, it also makes sense to keep them in one app so that it's one app to maintain(since roughly 50% of site look/functionality will be shared).
What we are trying to do is keep this as clean as possible so it's easy for multiple teams to work on and easy to maintain.
Some things we've thought about/are trying:
Engines. Make each app an engine. This would let us base routes on the domain. It also allows us to pull out controllers, models and views for the specific app. This solution does not seem ideal as we won't be reusing the apps any time soon. And explicitly stating the host in the routes doesn't seem right.
Skinning/themes. The auth logic would be different between the apps. Each user model would be different. So it's not just a skinning problem.
In app/view add folder sitea for sitea views, siteb for siteb views and so on. Do the same for controllers and models. This is still pretty messy and since it didn't follow naming conventions, it did not work with rails so nicely and made much of the code messier.
Making another rails app. We just didn't want to maintain the same controller or view in 2 apps if they are identical.
What we want to do is make the app intelligently use a controller based on the host. So there would be a sessions controller for each app, and perhaps some parent session controller for shared logic(not needed now). In each of these session controllers, it handles authentication for that specific app. So if the domain is a.mysite.com, it would use session controller for app a and know to use app a's views,models,controllers. And if the domain is b.mysite, it would use the session controller for b. And there would be a user model for a and user model for b, which also would be determined by the domain.
Does anyone have any suggestions or experience with this situation? And ideally using rails 2.3.x as updating to rails 3 isn't an option right now.
Devise does exactly this. You would do well to check out its architecture and apply that architecture to your own case.
You will have multiple separate Rails applications. The shared code will be a separate project, perhaps distributed as a gem or at least a separate Git repository. The shared code will include many controller actions and many view templates that are there to be sensible defaults, and which will be overridden in some apps but not in others.
All the custom code for application A will belong in a project solely devoted to containing the custom code for application A. It will be its own fully-functioning Rails application and will depend heavily on the majority of the sensible defaults provided by the shared code in the shared-code project.
I've used the theme support plugin before and dynamically set the theme based on the request uri:
http://mattmccray.com/svn/rails/plugins/theme_support
It will probably need some work to support Rails 2.3.
Update: Looks like there's a rewrite: https://github.com/dasil003/rails-multisite
Sounds like you want to make the 'base' app a plugin and use that in each of your site apps. You can use something like svn-extern so it's automatically updated whenever something changes.
I am building a new Rails-based application that will have Basecamp-like accounts for each subdomain. Each account (client/customer) should be allowed to store different settings such as a color scheme, their subdomain, their preferred authentication mechanism and so forth.
So, how should I handle the settings for each account such that I can easily add new settings later that apply to all accounts? Examples or ideas of how to build the objects and relationships (i.e. many-to-many) would be great. Additionally, if you have any good articles, I would greatly appreciate a link to those. This app needs to be highly professional and I want to make sure that I get some of these basic things right before I jump into the remainder of the project.
Thanks very much!
This question addresses a similar situation. It's worded a little differently. But if you map the question's description of a product to one of your subdomain it still feels pretty relevant. You're not explicit but with the comparison to basecamp I'm assuming that each subdomain will have it's own set of users who also have their own settings. Settings that might not be global to your application. The linked question address that too.
I see this working best as a single table for subdomain settings.
With an index on a column linking it to a customer/client/userid, another one linking it to a subdomanin.
Each option that effects subdomain design gets a column in this table. On page load just look up the row for the subdomain in the table in a before filter and things should go relatively smoothly. Adding new global options are simple. Just graft another column onto this table with an appropriate default value.
We have an admin application used to manage member data and it was built in 2.1, has been running for about a year. Now that all inputs and data massage is done, our client wants to start building member site, members will have access to data the administrators have been inputting.
Here's the question, should we start a new Rails app hooked to the same admin database or should we create a new Rails app in different db with master-slave settings? The good thing about creating a new Rails app is obviously taking advantage of the new version, which we like. Or ..maybe just build the member site in the same admin app?
THanks,
Why don't you want to build the member site in the same admin app? Too much legacy?
You can use the same database but the problem is you will have to enforce any conditions you have in your models directly in your database (mandatory fields, model relationship and so on).
And I can see a lot of duplication code happening between the two apps. At least for the models. Which is really wrong :(
I don't recommend making two separate applications but It is hard to answer without looking at your app and without knowing more details.
Or build a new app using a copy of the existing database?
There's no reason the two applications cannot share the same database.
However, there's probably a number of reasons why they shouldn't. But, the only way you're going to figure those out are by going through the changelog of ActiveRecord's database adaptors.