Documents on a rails website - ruby-on-rails

I am developing a portal of sorts in Ruby on Rails using PostgreSQL.
I require different pages (each page represents a different topic of interest) on the portal to show different documents. The admin will have the ability to upload additional documents to each page.
No where is the entire list of documents on the website required
What is the best practice to implement such a system and is there any tutorials for the same?

It sounds like you want a content management system. Alchemy CMS is a good choice for rails.

That's a multi-tenant application, and normally you do this by associating all the records with a user or an account, sometimes both. This is done with a has_many/belongs_to pair most of the time for any records that are user or account specific.
You'll also have to be specific in each controller to only access records that the person can see, so you'll need to define an access control mechanism of some kind. There's modules for this, writing your own can be tricky.

Related

Role based authorizations or different tables in a ruby appointment booking app

I have seen regular debates about the way to manage the different class of users.
Usually, it seems that developers prefer a role based approach (e.g. user, admin,...) with gems like Cancancan
But I'm wondering if it's applicable for an appointment booking app (appointment for doctors, teachers,... or even bookings). Indeed in this case, the 2 types of users have access to totally different pages. In its documentation about associations, Ruby on Rails guide takes the example of a medical appointment booking app with 1 table for doctors and 1 table for patients.
For this kind of app, I'm a little bit lost regarding the most efficient solution!
Thanks!
You can use a tool like Cancanan to break out the different roles and abilities, then restrict access to certain parts of the system based on those rules.
Additionally you can display only the relevant navigation or pages when the user's accessing the system so they might not even be aware of what they're not seeing.

Rails 4 - Multiple apps using centralized database

Suppose we have this scenario:
www.main.com - Main interface where admin (foo, bar, etc..) can store products, based on their own e-commerce
www.foo.com - Sample store that sells items from the "foo" store
www.bar.com - Sample store that sells items from the "bar" store
The problem is finding a way to centralize the database structure and models.
I prefer to keep every single store in separated apps (so I exclude rails engines).
For instance, if a user buys something in the "foo" store, I need to interact with the main db and update it.
How can I do this?
Rails works much better with a "one database, one app" model. There are lots of ways how you can share models across apps (gems, engines, git submodules, etc), but none of those ways is great. You end up introducing lots of overhead in your development, deployment, and testing process. You also invite lots of hidden dependencies between code, as Rails doesn't give you easy way to keep clean abstraction (for example, you wrote a helper for store Foo, and then your coworker used that helper in store Bar, and then every time you change Foo, Bar breaks).
I recommend a centralized API approach instead:
api.foobarmain.com - a app/service that provides RESTful API for all the functionality of all stores.
This app has all the db models, and it exposes them as resources in the API for other apps to interact with.
This app can have an admin UI for all the stores, if you need it. Alternatively, admin UI may be another client of an API.
www.foo.com - a full stack app that interacts with API at api.foobarmail.com
There is no shared database connection to API, everything that you need to interact has to be exposed via API.
There will be no shared code between www.foo.com and www.bar.com. Code reuse happens only by virtue of using the same API app/service.
From the perspective of www.foo.com, the model layer (in MVC) is powered by API, not by database.
You can still have its own database on www.foo.com if you need to store data specific to www.foo.com only.
www.bar.com - another full stack app that interacts with API
so on ...
Another way is using multiple schema if you are using Postgresql. I have a similar issue with a new project that I about to start.
You can use gem 'apartment' to deal with different schemas. The queries will be a bit complicated but with different schemas you will end up with one database and you can create different namespaces to respond accordingly.
You can set up so app select the correct schema based on the Domain or Subdomain.
Here is the link: https://github.com/influitive/apartment

Rails: database-handling for an international ecommerce app

Edited
The question in short:
Is there a way (a gem?) in Rails to bind two databases of same schemes to an app, where Rails decides which db to use on top level domain?
For example: if user entered example.de the data on site loads from a db called de_example_production and if it's example.com then the data is loaded from us_example_production.
Details (old question):
I have an ecommerce Rails app that has been developed for some particular country. Now I am trying to extend it to another country.
The main requirement is that it should be the same app running on the same server (so that code updates apply to all countries), but since the countries have different data - cities, stores, products - I want to them to be on separate databases. What's the best way to achieve this?
As an alternative, I thought of continuing with the current database by adding a country model on top of the hierarchy of models that I already have, but it seems to me this approach will add a lot of complexity and redundancy to the system.
Can you please help me out?
As Thomas pointed out, the paradigm I was looking for is called multitenancy. I decided to proceed with the Apartment gem as it perfectly suited my requirements.
These pro railscasts helped me in my implementation:
Multitenancy with Scopes
and Multitenancy with PostgreSQL.

Multisite application in Rails (like shopify.com)

I would like create web app like shopify.com.
User can pickup subdomain(or domain), theme and have own store.
How can I do this?
Create main application, deploy it automatically like new standalone version and update it via git?
I'm using Rails 3.
Thanks for your advice.
Based on replies:
When I choose to use only one application (without multiple instances) and give user his subdomain, it will looks like their own website. But everything will be in one database (It's good idea?). And how can I have multiple themes in Rails app?
Take a look at LocomotiveCMS, specifically the routing system. Locomotive actually hosts multiple sites inside a single rails application. It does this by inspecting the request URL when it comes in and setting the current_site variable with the site which is set up to handle the domain. Then the current_site is actually just an object which contains all the pages, contents, settings, etc. for the specific site being served up.
So to answer your question, I think a good solution is to give your rails app the ability to serve up multiple sites based on the domain. It's not that hard, and it seems less fragile to me than trying to automatically deploy new instances of an app.
So far I have understood, you want to let your users have their own subdomain, different theme but the functionality would be same right. Users just need to have a feel of something of their own.
Well definitely, you need to have a single application that supports multiple subdomains.
A quick googling gave me [ http://37signals.com/svn/posts/1512-how-to-do-basecamp-style-subdomains-in-rails ]. May be you can get some insights from here.
For example if your service is http://www.myfi.com, a brief idea can be:
When a customer is registering, you should let him choose his subdomain. And the newly created account will be associated with this subdomain with a url. Say, http://customer1.myfi.com.
You should register for domain *.myfi.com so that anyone in the world hit with anysubdomain.myfi.com, it comes in your application.
Then from the url part, you should identify the subdomain (customer1) that is being used, and need to set that in session.
Now when someone will try to login, you must verify the account in the context of that subdomain's account.
In fact, all following actions need to be handled in the context of the subdomain's account.
Just tried the gather a glimpse of the implementation here. If you have confusion about something specific, share that also.
Edit:
Whenever you are thinking about multiple theme, you must have simple design which is completely driven by css and js. The app/view files should contain only content and HTML nodes with class names or ids.
Generally a UI designer can put more helpful ideas about how to make such theming mechanism. But all I can feel is, based on the chosen theme by customer, you have to load different css and js.
Actually the strategies can be indefinitely sophisticated and scalable, but its always wise to start with something easy. Then ideas will automatically evolve into better ones.

Examples using Active Directory/LDAP groups for permissions \ roles in Rails App

I was wondering how other people implemented this scenario. I have an internal rails app ( inventory management, label printing, shipping,etc). I'm rewriting security on the system, cause the old way got to cumbersome to maintain ( users table, passwords, roles) - I used restful_authentication and roles. It was implemented about 3 years ago. I already implemented AuthLogic with ruby-ldap-net to authenticate users ( actually that was surprisingly easy, compared to how I struggled with other frameworks/languages before). Next step is roles. I already have groups defined in Active Directory - so I don't want to run a separate roles system in my rails app, I just want to reuse Active Directory groups - since that part of the system is already maintained for other purposes ( shared drives, backups, pc access, etc)
So I was wondering if others had experience implementing permissions/roles in a rails app based on groups in Active Directory or LDAP. Also the roles requirements are pretty complex.
Here is an example:
For instance I have users that belong to the supervisors group in AD and to inventory dept, so I was that user to be able to run "advanced" tasks in invetory - adjust qty, run reports, however other "supervisors" from other departmanets, shouldn't be able to do this, also Top Management - should be able to use those reports (regardless weather they belong to the invetory or not), but not Middle Management, unless they are in inventory group. Admins of the system (Domain Admins) should have unrestricted access to the system , except for HR & Finances part unless they are in HR ( like you don't want all system admins (except for one authorized one) to see personal info of other employees).
I looked at acl9, cancan, aegis. I was wondering if there are any advantaged/cons to using one versus the other for this particular use of system access based on AD. Suggest other systems if you had good experience.
Thank you!!!
ActiveLDAP (Documentation, Github) has some of the features you're looking for, specifically:
You can map LDAP objects (Object Class instances) to objects in a Rails application. The API doesn't mirror ActiveRecord exactly, but it's pretty easy to understand and learn.
It's obviously not possible to join, etc. across LDAP and Relational Databases, but you could write some mildly clever code to make composite data easily accessible from either the ActiveLDAP object or the ActiveRecord object.
ActiveLDAP also provides methods to write to LDAP which allows you to manage your users and roles in LDAP from rails, eliminating the requirement to manage a user table in the database, however, a user database table would likely still be necessary to store application specific data about a user.
Additionally, you could integrate AuthLogic with ActiveLDAP. Here's one attempt I found of just that: LDAP Pass-through Authentication with Authlogic and ActiveLdap
You could then use Declarative Authorization (Pundit) to handle your roles and authorization.

Resources