Newbie learning Rails and about to undertake my first real app. Please bare with me, I’ll try not to be long winded.
It’s a blogging app where blogs belong to organizations, not users. An organization can have many blogs, a blog can have many admins, and many subscribers. There can be many organizations.
My many objects are: Organization, User, Blog, BlogSubscription (this is a joiner table association a blog with a user)
An Organization has many blogs and belongs to a user
A User has many BlogSubscriptions and (has one or has many–yet to be decided) organizations
A Blog belongs to an organization
I’m thinking of having two sign up processes. A) for organizations, B) for ordinary users who subscribe to blogs
So for sign-up A: User signs up and the app creates the user object and an Organization object attached to the user. This is an account-level object.
For sign-up B: User finds a blog and subscribes, or signs-in/signs-up then subscribes. This is a user level object.
I’m afraid that the way I plan to go about might give me a headache. Areas of concern:
Roles. How to implement role based security and authorization.
Login. Should I roll my own or use something like Devise with OmniAuth
Organization level subdomain. So James signs up and creates an Organization, which should map to smiths.myapp.com
The closest real life app I can think of is UserVoice. I would appreciate any guidance, tips, or resources by anyone who has some knowledge or experience developing a similar app. I’m having a particularly hard time modeling my data.
I’m also new to Rails Dev, so my opinion is kind of imature, but for this instant, I really believe you should NOT be worring about those issues. If I were you, I would first focus on worring about getting my app to work properly, according to my specifications, strenghening my Object’s Relationships. Once that’s working as it should, THEN I would worry about authentication, permissions, subdomains and stuff.
Trust me, It will be a lot of hard work for you to reach the level of “Ok, there I go. My app is working smoothly and well tested. That’s what I was talking about when I decided to start this whole thing up.” So focus on what’s right in front of you, the basis of your rails app.
And then go through this path of “Wow, what the heck. Regular users should NOT be able to reach organization’s settings and stuff. I need to restrain that”
See what I mean? Developing is like polishing a jewelry to a client. It’s a really delicate art, and that you don’t start it by trying to do it perfectly at the first try. No, you need to lapidate that rough diamond into a elegant, delicate and beautiful jewelry. Make your sketch, and then lapidate your app until your rough app, becomes an awesome, robust, secure and consistent app!
Sorry If I got a little carried away, but. That’s my advise
my rudimentary understanding… you need these all to be has_many :through relationships and you need only one person model and new relationship models to account for privileges.
user
has_many organizations, through memberships
organization
has_many users, through memberships
membership
belongs_to user
belongs_to organization
same with blogs and members with subscriptions being the through relationship.
importantly, then the blog has many editors through privileges, with editor pointing back to the member table and privileges belonging to a user/editor.
in this way you allow subscribers to be promoted to a blog editor and editors being demoted to a plain subscriber without having duplicate database tables. you just edit their privileges, not destroy an editor and create a subscriber. very clean.
in short, you need RELATIONSHIPS tables and NOT more people tables. this as I understand things is a huge part of cleaning up your domain.
@Jordan, thank you for the explanation. I’m having a hard time seeing what the relationships model looks like: id, user_id, blog_id, relationship_type_id? In that, the relationship_type_id decides if the relationship is a user or an editor?
Blog
belongs_to organization
belongs_to editor through relationships
belongs_to subscriber through relationships
I also haven’t thought about a privileges table yet, so I’m unsure what that class would look like.
@Aline, it’s funny, I always approach a new app by creating a user model, then login and authentication. Interesting approach.
In the example given, it's a relationship between users and
organizations. the join table (memberships) would have a field
(column) named user_id and column named organization_id. All of the
tables, as is rails convention, would have a ID column which is the
primary key.
The relationship between organization and blogs would be one to many
(organizations would have many, blogs would belong to organization).
The blog subscription table would act in the same way as the
membership table above, only it joins blogs and users. User would
have many blogs through BlogSubscription and Blog would have many
users through BlogSubscription.
As far as login and authentication is concerned, I would consider the
devise gem. It can be added later, as the above post suggests, but
that can be a little more difficult. For example, I once rolled my
own authentication and later decided to implement devise. Devise sets
up a migration when it's installed. In my case, I was setting up
Devise on the User table. It tried to add an email column which I
already had, so the entire migration raised an exception.
Unfortunately, the migration it creates is a set of methods and the
code that adds the email column was buried in a method. The point of
this is that if you are going to use Devise, it might be better to
start up front with it. I recommend it because, in addition to basic
authentication, it adds capabilities such as confirming an email
address when a new user sets up in the system, locking the account
after a given number of unsuccessful attempts, etc. These tend to be
features an app like yours uses and it requires almost no coding with
devise.
With respect to roles, it depends on how involved your roles are. I
would leave this to a later iteration as one of the posts above
suggests. There's also a gem for this that is popular (cancan). I
have mixed feelings on it. It's heavily controller-based.
@Jordan, thank you for the explanation. I'm having a hard time seeing what
the relationships model looks like: id, user_id, blog_id,
relationship_type_id? In that, the relationship_type_id decides if the
relationship is a user or an editor?
Blog
belongs_to organization
belongs_to editor through relationships
belongs_to subscriber through relationships
I also haven't thought about a privileges table yet, so I'm unsure what that
class would look like.
@Aline, it's funny, I always approach a new app by creating a user model,
then login and authentication. Interesting approach.
You don't seem to have asked a clear question that can be answered.
Have you worked through (and understood) the Rails Guide on
ActiveRecord Relationships? If you make sure you understand that
fully then I suspect you will be able to answer your own question. If
there is something there that is not clear then ask for clarification.
@Colin and @Mike, thank you both, particularly, mike , for the part about devise integration. To wrap up, I would like your opinion whether there any flaws or major disadvantages to my structure.
I dropped the organizations table since I think its redundant. This leaves me with the following tables: users, relationships, blogs, relationship_types.
User has_many blogs through relationships
Blog has_many subscribers through relationships
has_many editors/admins through relationships
relationships will have user_id, blog_id, and relationship_type_id
relationshiptypes will have admin, editor, and subscriber.
I’m unsure about the last part: the relationship type id column. It would allow a User object to Admin, edit, and subscriber to many blogs. I’m not sure it it’s a good approach.
I’m further unsure whether to restrict the relationships table to one row per blog and user (thus ignoring the relationship type id col; so blog 1 and user 1 can have only 1 row in the relationships table; relationships can be upgraded and downgraded). This means permissions must be inherited from lower to higher roles, so it may not be flexible.
Any thoughts on this approach? Could it be done better? Just looking for thoughts… thanks!