Rails application architecture and common setup - ruby-on-rails

So I am starting out on company project that will have several components:
At first...
Job list
Client profile creation and management
User administration and access (login, signup, roles, etc)
later...
Messaging
Schedule
Basic reporting
way later...
Deeper analysis and bi
I'm wondering if it makes sense for each bullet item to be its own rails project, self contained and modular (if that is indeed the case); or if it's just best for it to be in the same app. I could envision a situation where each module could operate so independently of each other that it wouldn't need the rest (except for the user funcionality) and another situation where all modules would be used together.
It seems like to me that many tasks can be handled with a lighter framework like Sinatra (and then situated physically under the rails app). It also seems like it would be a lot of overhead to have several rails apps running on a server. But I am not totally aware of all the pluses and minuses to operating each scenario.
I know this is kind of a general question that is bound to get a lot of "it depends" kind of responses (and rightfully so) I was looking for opinions/examples of how you setup this kind/your kind of project in rails. I am a quasi noob so be gentle.
Thanks in advance!

Generally speaking I would consider a website to be a suitable target for a Rails app. Each part of the app can have its own namespaces within the app, so the app has some structure internally, but they should all be one application. Consider things like sessions, where you want a user to login and use whatever features of the site you want. You want those sessions in one application without a user having to login to different sections.
Saying that, if there is complex or extended functionality that isn't part of the MVC architecture (say talking to an external API, data-mining etc), then you could offset that to a separate project and a include it as a Gem in your application. You would still have one main Rails application that includes those Gems.
You might also want to bundle together a section of your project into a reusable Rails engine that can be loaded into multiple projects. For example, Devise handles user login and management. It is a Rails engine, bundled as a Gem, that you include in your project.
Another example from Meducation (one of my sites). I'm in the process of extracting our email tracking system out into its own Rails engine as I feel its functionality sits alongside Meducation and is not a core part of it. I can then use it in other projects as well.
In your specific example, I think your requirements fit fine in one Rails application.

Related

What is the conventional architecture for a Rails 5 API with an Administrative UI as well?

I was setting out to start a new Rails 5 API, and realized I also need a content-administration "site" of some sort. The admin tool is very simple, just a UI for very basic CRUD operations.
I have an instinct to create two separate Rails applications - one web application for the content-admin tool, and another web application for the API.
This brings about the problem with sharing data models, which is solvable by using rails engines, or including the models as a gem.
As I was researching solutions, I seemed to observe a pattern of including the content-admin portion within the API app itself. There are some middleware includes and controller inheritances involved in this, but its quite simple to get a content-admin UI to run within the same app as an API. Its much less work, and I dont see much of a problem with scale, since the content-admin UI is lightly utilized and the API is the core of the business.
Is this the accepted convention? I might be gaining a bias due to web search results, but it seems like the simplest and most common approach. I plan to have a separate server for accessing the content-admin vs accessing the API, which is what led me to originally plan this as two separate apps. Now I am thinking I was just getting sucked into the "microservices" hype, and it seems more conventional to just include the content-admin UI with my API app.
On the other side, everything I read about Rails engines is 3-4 years out of date. There is little information (that I am stumbling upon) within the last year or so, and more specifically, little-to-no information concerning Rails 5. I am wondering if this sort of architecture has fallen by the wayside.
Is there a typical convention for Rails 5 API applications that also need a content-admin UI?
The approach I've used before is to have the api running out of /app/controllers/api and then have the ActiveAdmin gem installed, with the admin interface files in /app/admin. You can set up the routes to serve the admin interface at https://api.yourapp.com/admin and the API at https://api.yourapp.com/api/v1/ or similar.
I don't know how much of an accepted convention this is, but it works fine.

How to decompose a Rails app into different small apps ecosystem

My team has been developing a bunch of modules in a monolithic Rails app for internal use. The modules are for example leave request, staff info, tasks/todo etc. Each module has its own purpose but somehow is linked to common information such as staff profile and user authentication. Each module has a developer assigned and they commit code to the same Rails app. Currently, it's super hard to maintain the code and scale. Now, I'm doing my research to decompose the app into small distributed apps and make them an ecosystem. Here are the concept I'm looking for:
There should be a master app that maintain the views of other client apps. Better yet, it acts as a platform for other client apps to plug in to it. Staff logs in to this master app to access client app.
Master app should render views of client app using AJAX or other ways (not decided).
Although, I want to decompose the apps, but each app should still be able to query resources/data such as staff profile from other client app in the ecosystem.
Actually, I have not decided about the interaction of each app. Thinking to us RESTful (not decided).
It should support development environment where each developer can develop each app independently. Hence, maintaining their own code in their own git repository. This is probably the main purpose of decomposing the app in the first place.
I'm reading Service-Oriented Design with Ruby on Rails book, but it seems like they focus on decomposing an app into small different services, whereas I want to have small different apps. Just wondering if there's any other ways to do.
Sorry for a long question and asking too much. Just want to know if you have been in the same situation and can guide me to some articles, communities, books so that I can continue more on my research.
Ah the joys of refactoring. It can be a tricky dance trying to structure an application into logical groups so that parts can be decoupled.
I would strongly suggest looking into Engines, with the Engines vs Mountable being very informative. This allows you to build a mini Rails app (aka an Engine) that can be packaged as gem. The custom Engine gems are bundled into a Rails app, providing a complete set of configurable functionality (models, controllers, views, etc).
The usefulness of Service-Oriented Architecture depends a lot on what kind of data you are pushing and pulling around. That being said, Rails is really wired for RESTful, so you get a lot of bang for the buck with that route.

Rails Authentication via Web Service

So, this may be a kind of dumb question, but I checked the Google and got no hits. We want to host multiple Rails apps in a way that makes them look homogeneous. We want all the apps to have the same look and feel, and all the apps to use the same sign-on database.
Theming I think we could accomplish by just putting the site theme into a gem, and requiring that gem from our github repository in each app. However, auth is trickier.
I know that I can achieve this "for free" by just not making the different portions of the site (store, chat forums, etc.) different apps. If they're all, say, Rails Engines, we can basically drop them into the same application with their own namespaced routes, and have a single plugin that does auth.
However, for various reasons we'd like to keep these separate apps, if that's technically possible. The number one reason is scalability; since this will be a hosted site, we want the flexibility to spin up more instances of, say, the store (perhaps to handle a holiday sale rush), without needing to spin up the chat forums. Also, we want to be able to completely isolate the portions of the code that AREN'T intertwined.
Ideally, the databases would be separate too (keeping us from falling back into the rut of "put everything including the kitchen sink in the db"), but I do know that one "cheap" way to do cross-app auth is just to use the same plugin (say, Devise), and just point to the same DB.
So, I'm thinking that maybe the way to do this is to auth via a web service call. Is this prior art -- does anyone have a gem for this that "just works" so that authentication can be shared across all apps? Or am I just entering into a world of pain by trying to build things this way?
Thanks in advance!
You could do a single sign on approach described at:
http://blog.joshsoftware.com/2010/12/16/multiple-applications-with-devise-omniauth-and-single-sign-on/
The single sign on approach with oauth and devise has some drawbacks. The main problem I had was I was unable to extend the timeout time across multiple apps.

Multi domain rails app. How to intelligently use MVC?

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.

How to consolidate multiple rails application and share ressources

I have thi intranet I developped back then with PHP.
I handles multiple apps and tools (blog, link sharing, file sharing, events, clendar...), and a big user autenthication system for logging in and authorisation management.
I'd like to start re-building it with Rails.
I don't want to build one big app.
I'd like to build the site as multiple smaller apps, sharing a few common ressources like the user administration system, templates, layouts and navigation...
Rails Engine provide a way to embed an app into another.
I guess I could have a "main" app, embedding all other apps.
But I don't feel it's the right way (I may be wrong) if I have 10-15 different apps.
How would you do it ?
Thanks.
We've created applications that are split into 2 - the user facing site and an admin site. We just made 2 separate sites that have the same db and models and their own views and controllers.
This works pretty well and gives us the freedom to treat each site differently in terms of security and deployment.
I don't have any experience in going farther than that.
Check out ActiveResource - it is designed to allow you to use RESTful webservices as if they were ActiveRecord objects.
I'm working on a project now with a bunch of separate sub-apps that are pure web services (no UI). There's one "main" application that has all the UI and handles login/authentication, and then accesses the others via ActiveResource.
You can share the models between projects adding
config.autoload_paths << Dir["SHARED_MODEL_PATH/app/models/*"]
to your application.rb config file.
Or you can check the tutorials about ActiveResource such as:
http://andywaite.com/2010/12/22/activeresource-layered-rails-app
http://wholemeal.co.nz/blog/2010/03/08/active-resource-associations-and-nested-resources/
http://ofps.oreilly.com/titles/9780596521424/activeresource_id59243.html

Resources