Rails app with one set of models, but two server processes (e.g. users and admin sections are separate) - ruby-on-rails

Suppose that you wanted to create two apps, both on Rails, but they share the same set of models. I'm certain I could 'hack' something together, that would probably work, but I'm curious what the best approach is.
Oh, and if you're curious about motivation: I want to freely restart the admin processes without disturbing the user processes. Also there is a bit of extra security not sharing the same session.

You could create a gem or engine with your models in the lib directory. Then they could easily be used by more than one Rails app. Google "rails engines" and you should get some ideas. If all you're doing is models though, a fullblown engine may be overkill and you can get by with a simple gem.

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.

Rails application architecture and common setup

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.

Scaling Out: how to handle communication between Ruby on Rails applications?

I am running Ruby on Rails 3 and I have an application that makes use of namespaces in order to handle more "internal concepts". With "internal concepts" I mean that each namespace is used to handle a specific resource of my application. For example a namespace is "users" and it is used to handle user's sessions and authorizations, another is "blogs" and it is used to handle all about posts and comments.
I think this is a "convenient" solution to avoid a lot of problems, but not the best.
At this time my RoR application consists of this file system structure:
# "users" and "blogs" are namespaces
RAILS_ROOT/app/controllers/users
RAILS_ROOT/app/controllers/blogs
RAILS_ROOT/app/models/users
RAILS_ROOT/app/models/blogs
RAILS_ROOT/app/views/users
RAILS_ROOT/app/views/blogs
...
I would like to switch the "users" and "blogs" namespace in two RoR applications using subdomains to have something like this:
http://main.com # This is the main RoR application
http://users.main.com # This is another RoR application used to handle users
http://blogs.main.com # This is another RoR application used to handle blogs
In few words, I think I am trying to Scale Out* my application or maybe to create a Webservice for each RoR application, but my issues are:
1. What problems I may encounter?
I noticed of problems about maintaining sessions (in my case I handle those with cookies) between applications but I think it isn't the only one problem.
2. How to handle communication between the three RoR applications in my case?
I noticed that I can use ActiveResource to share information, but I must pay attention to information such as user authentication.
I have to implement the OpenID/Oauth protocol in order to maintain user authentications?
I think I have to ensure the user authentication information with a HTTPS connection also if the comunication is between subdomains. Is it true?
3. How do I organize my work and resources?
With all that being said, I would like to don't use (absolutely) plugins or gems, but, if I need, I would like to implement my own handler.
At the end I would like to have 3 RoR "easy" and separated applications without use namespaces in each of them and that can communicate between each other:
# "Main" application for http://main.com
ROOT_MAIN/app/controllers/
ROOT_MAIN/app/models/
ROOT_MAIN/app/views/users
...
# "Users" application for http://users.main.com
ROOT_USERS/app/controllers/
ROOT_USERS/app/models/
ROOT_USERS/app/views/users
...
# "Blogs" application for http://blogs.main.com
ROOT_BLOGS/app/controllers/
ROOT_BLOGS/app/models/
ROOT_BLOGS/app/views/users
...
BTW: is a good approach the usage of namespaces that I'm doing?
P.S.: If you need some other information, let me know and I will update the question.
*From The O2 Software Process: "Scale Out" refers to the concept of adding more servers to an existing park, as opposed to "Scale Up" which means to replace existing (slow) servers with newer (and faster) servers.
You problem is lot more simpler than you think. It all depends on how you handle your routes.
Ruby On Rails 3 has better support for Subdomains. So, you need not separate them into three/more RoR apps. You can put all your code in one single RoR app. And redirect user.abc.com to any controller like "users/sessions", redirect blog.abc.com to "blogs/blogs" controller. namespaces are convenient in apps like yours where they make your job really quick to separate out contextually different parts of your app in different folders and route formats.
Try the namespaces to your hearts content, I believe you won't get any errors you are imagining right now. I'd suggest you write code for it and come here if you face problems in it.
Is your app really so big that you need to use multiple apps to handle the different concerns? It could be that your post just lacks enough detail to convey the real magnitude of what you are doing but it seems like you are trying to modularize a small enough app that it would be fine without "scaling out" as you say. Or maybe I am just missing something?
I think that is going to be a tricky problem but there may be some way to store session data in the database and either share it the way you handle #2 or you'll have to roll a custom solution for that. I think the biggest problem will be sharing resources across your app, and also if you are breaking user management out into its own app you'll need to implement your own OpenID/Oauth. This post describes this with Devise/OAuth.
You can use activeresource to connect to each app's respective rest api. This post describes one guy's solutions to sharing data across rails apps.
This question is somewhat vague. You described using multiple apps to separate your concerns (blogging vs user management), so I imagine you'll have your resources at the root of each application without any namespacing, as you've done already in your existing application.
Now for a more general response to your entire question, recently I read a blog post regarding Data, Context and Interaction (wikipedia article) on Rails, and I think this might be a better solution for what you are trying to accomplish if you feel like your app is getting out of control.
Sorry for answering this late.
Actually if you want to scale your rails application you need not create different apps for each unit(I mean as you are trying to separate out users and blogs here), you are jumping a step ahead in the process of scaling your app you should first put all individual units as mountable engines and require them as gem in your core application and mount them in your core app routes.As in your case blogs can be moved to a separate mountable engine.If in future you require to scale more then you can move futher to use engines as separate application.Here's a link to a video that may give you idea what I am trying to explain here https://www.youtube.com/watch?v=pm94BsoMGik

How to extend an existing Ruby on Rails CMS to host multiple sites?

I am trying to build a CMS I can use to host multiple sites. I know I'm going to end up reinventing the wheel a million times with this project, so I'm thinking about extending an existing open source Ruby on Rails CMS to meet my needs.
One of those needs is to be able to run multiple sites, while using only one code-base. That way, when there's an update I want to make, I can update it in one place, and the change is reflected on all of the sites. I think that this will be able to scale by running multiple instances of the application.
I think that I can use the domain/subdomain to determine which data to display. For example, someone goes to subdomain1.mysite.com and the application looks in the database for the content for subdomain1.
The problem I see is with most pre-built CMS solutions, they are only designed to host one site, including the one I want to use. So the database is structured to work with one site. However, I had the idea that I could overcome this by "creating a new database" for each site, then specifying which database to connect to based on the domain/subdomain as I mentioned above.
I'm thinking of hosting this on Heroku, so I'm wondering what my options for this might be. I'm not very familiar with Amazon S3, or Amazon SimpleDB, but I feel like there's some sort of "cloud database" that would make this solution a lot more realistic, than creating a new MySQL database for each site.
What do you think? Am I thinking about this the wrong way? What advice do you have to offer in this area?
I've worked on a Rails app like this, and the way it was done there was named-based virtual hosts, with db entries for each site running. Each record was scoped to a site if necessary (blog posts, etc.) while users would have access to all sites running out of that db. Administrator permissions could be global or scoped to one or more sites.
You're absolutely correct when you say you'll reinvent the wheel a million times during the project. Plugins will likely require hacking on top of the CMS itself.
In my situation, it ended up being a waste of almost a million dollars of company money to build that codebase to run multiple sites while still being able to cater to the whims of each client site. It worked, but was not very maintainable due to the number of site-specific hacks that subsequently entered the codebase. You may be able to make it work if you don't have to worry about catering to specific client sites running on your platform.
In the end, you're going to need a layer of indirection to handle the different sites regardless of methodology. We ended up putting it in the database itself. If you go with the different-db-for-each-site method you mentioned, you'll put that layer in your code instead. I'm not sure which one is the better method.
I hope you're able to pull this off. I failed.
Also, as I learned today, Heroku offers postgres instead of mysql for rails apps.
There's James Stewart's Theme Support Plugin for Rails 2.3, and lucasefe's themes_for_rails gem for Rails 3+.
I just started using the 2.3 version and it's working well so far.

How to turn a single-site app into a mantainable multi-site app without code changes?

It's an application that we use internally at the office that I would like to offer as a hosted service for anyone.
How can I do that without making major code changes?
The first thing that occurs to me is to have the app select which database to connect to based on the domain.
So each instance of the app would have its own database, but all instances would share the same code.
The only changes required to the code would be the database selection.
Is this approach maintainable? I've heard wordpress.com does this and that it offers a couple of advantages. I'm mainly looking to do it this way to avoid have to scope my entire set of database queries to a certain site within the same database.
Thanks!
The simplest way to do this is to clone the application, and create another server instance to handle it. This actually the way I handle multiple wordpress blogs on my server
Pro:
This process can be streamlined into a utility script.
Can be easily maintained if symlinks are used for the common code. IE: Everything but branding and some of the things in the config directory.
Cons:
- If you're using passenger it will require an apache restart for each new instance.
- Same if you're using Apache to route subdomains on different virtual hosts to different mongrel clusters.
However the better way comes from the question: Rails - Separate Database Per Subdomain
The method in the accepted answer is much more robust. It might require more changes than you're looking for, but it has all the benefits without the drawbacks of any other methods. Each new instance requires a new entry in the master database with the table name and other instance specific information. You'll also want custom rake task to build the database for each new instance.
I would suggest switching the database connection and adding a view_path based on the domain, I have posted code in this question.
I hope this helps!
I wouldn't do this with multiple databases as you mentioned. Keeping all your schemas/migrations in sync with all the db's could become painful.
I would look into simply making it a multi-tenant app where you have some sort of "Account" model and then all your existing models are scoped to it ... in other words, if this was a blog app, your Account has_many :posts, etc.
With this approach, you can identify accounts by subdomain ... have people choose their subdomain when they create an account and go from there.
It's pretty straightforward to do. If you need add billing into the mix, you might look at the SaaS Railskit (which handles all the signup and subdomain stuff) or Chargify.
You can also identify accounts Twitter-style ... with http://myapp.com/someuser

Resources