I'm working on an app with Project, User, and Group models. A Project has many groups, a User belongs to many groups through a Membership model. I have two choices:
When a Project is created, a default group is created. Any person participating in this project is automatically added to it.
Make Memberships polymorphic so that users can be a member of a project, and a group in the project.
Both approaches have wider implications: Other models will come into play, such as: File, Post, and Task.
If I go for option 2, those models will also have to be polymorphic. But it would simplify things a bit.
If I go for option two, I forgo polymorphism, but things get a bit complicated. For example, finding the users projects means I have to query for the user's groups, then projects associated with those groups, and then make sure the projects are unique.
Has anyone faced a similar situation, any advice or additional pros and cons for either approach?
I really would rather ditch groups altogether, but it's a requirement for permissions, to separate content based on group.
I think best option would be creating a default group, because:
Then you can go with a clear structure:
projects - has many groups
groups -> has many users etc,
you will have the flexibility of managing groups easily
your core structure is simple, hence years down the line, easy to expand
you are easing the work flow of user by automating a one step. I personally believe if you could let a user to up and running quickly, they will find your system user friendly
Related
I am trying to implement a feature to my project (kind of like a social media site) that could be either basic or complex and I am not sure if I am going to take forever reinventing the wheel or just go on a crazy tangent that won't work. I just need to "check in" so to say.
I am going to use Facebook terminology as an example to simplify the concept but implement similar features with different names. In Facebook you have Pages and Groups, which are similar yet have slight differences (from now, I will call the collection of these DataSets). Both of these can have multiple admins or followers, which are all User roles, and each User can have roles for multiple Groups and multiple Pages (one role per Group or Page). Then for example, you can click a drop down to change your account to post as a Page you are an admin for.
Essentially, the concept I am describing is where a single User can have a role for multiple different types of DataSets. For example, a single User could follow 30 different Pages and 10 different Groups, and be an admin for one Group and two Pages. Does the concept I am describing belong to a particular concept or software design pattern? I am finding it really hard to describe this feature without using Facebook examples.
I have a strategy to implement this type of functionality in Rails, but I feel like using this strategy would be making the problem harder than it is and there is a fancy rails way of doing it, or a Gem, but I just don't know how to research it due to lack of terminology to describe my problem.
Current strategy is:
I have a Users table from Devise. Pages and Groups are each individual models and have their own tables. I have matching database tables to make the many-to-many relationships between Pages and Users, along with Groups and Users (e.g. 3 column design, column for the user_id, column for the page_id and the type of relationship such as admin or follower). Let's call these Group_User and Page_User. I am being flexible at the moment as I may add more DataSets similar to Page and Group.
Then for the Devise User table, I have an extra two columns to track the DataSet that the User is an admin for and currently posting as. One column is for the DataSet type and the other for the id for this instance (e.g. [Group,1] is stored in these two columns to represent Group with group_id:1 and [Page,3] is used to represent Page with page_id:3). These two columns can be checked when displaying options relevant for admins in that Group/Page and a simple drop down at the top of the site changes the values in these columns to any of the Pages/Groups the logged in User is an admin for. This way, one User login can take on many admin roles and change between these easily as needed.
Is there a better way to do this in Rails, such as a gem or specific design pattern? Or am I on track to implement these features myself? I think I understand the problem but my solution just seems simple/raw and possibly might have unintended consequences later down the track (e.g. it seems database intensive).
One way I was thinking of doing this was making a concern that includes methods to build the relationships and pass in the name of the DataSet as an argument, just so I am not rewriting the same methods for Pages, then Groups, then whatever comes next.
I looked at other solutions such as polymorphic typing (which I think is good for if each user only had one role or only managed relationships for one group or one page) and Single Table Inheritance (but I think my Pages and Groups might be too different for this to work). I thought about using inheritance as well (e.g. a parent for both Group and Page) but I am not sure this helps much.
I am just a guy that studied too much computer science and not enough software engineering. Any tips on how to simplify this problem or just a simple "yeah that will work" would be really helpful!
I think you are going great in the database design. Once participated in a social media application like yours which had similar type of design. Your design seems much better than the one I worked with. In my opinion this type of applications are supposed to be database extensive.
There are several design patterns used in RoR. One I heavily use is Service Object Pattern to maintain thin controller and models. Also it helps me to write reusable class.
Another one I like is the Presenter Pattern to simplify views.
You can have a details look at this blog post for more design pattern ideas.
If I want to build a Rails app that has two different types of users, let's say one type is called players and the other one is owners, what is the best and most efficient approach to modeling the app?
Things to take into account:
There should only be one Login, but different Registration forms that Owners/Players can use.
Owners can have access to a control panel but Players cannot.
Owners cannot share any of Players capabilities, but both need to be able to perform Login/Registration.
I am not using Devise, so please do not suggest it.
Different Approaches I've considered:
Using cancancan gem, but it does not really seem to meet my needs in the sense that I am not looking to create a user/admin hierarchical approach but rather a if you're a Player, then you can see these pages and perform these actions but Owners cannot and vice versa. Almost like splitting the app in two. cancancan seems that it would treat Owners as "Players with extra privileges", not different privileges entirely.
Creating separate models with separate login and registration forms, which seems like a disaster waiting to happen. One small mixup between a Players table and the Owners table, especially with the primary keys, and that will be a world of trouble where people could end up logging in to the wrong accounts.
Creating a polymorphic or has_one relation toward an Account model, which so far, seems like the best way to probably go about it. If I created a polymorphic Account model, I can store different types of Players/Owners, but how could I compare login credentials against all types?
I had been trying to find something on this matter regarding how to map this out and was surprised to not find an information on how to do this without using Devise. If anyone has any good links they can point me to that also address this matter (without Devise), please leave them in your answer! Thanks.
I'd suggest one User class with a type attribute that determines whether the user is a Player or an Owner (single table inheritance). This way you keep the registration logic in one place but can customize the forms depending on the user's class.
There must be alternatives to cancancan that help with what you want to do, or you can implement helpers yourself:
def can_access_control_panel?
current_user.is_a?(Owner)
end
You have to have a way to separate one user from another. One way is to add an attribute to the User table so you can call current_user.role and it will return "owner" or return "player".
I have used Pundit gem in the past. It lets you define which controller actions the current user is allowed to access. So as you create resources for your application, you can add a policy that specifies who is allowed to that given resource. This is the repo to the application.
This answer might help you.
I'm building out a SaaS application that allows an individual to signup and create an exclusive Group. The admin will then be able to add people to the group by e-mailing them (this will be used primarily internally by companies).
Unfortunately, I'm quite new to Rails and thereby not too sure where to begin.
All groups should be mutually exclusive and users should only be able to belong to one group.
Any suggestions of where to begin in terms of the Group / user relationship?
Thanks a lot.
In terms of the relationship between Users and Groups, it will be a one (Group) to many (Users) relationship. Bringing rails into context, you can take a look at ActiveRecord associations to give yourself the right knowledge about the types of functionality that's exposed. Everyone user :belongs_to only one Group, and Groups :has_many Users. If you need a primer on database relationships, you can check out any primer like this or any link you can find with some diligent googling.
You can try out some things and come back once you have something going, then others will be able to help you out more. If you are REALLY new to Rails, you can check out and try the running example here. Good luck.
I'm having a bit of trouble wrapping my head around something. Basically I'm starting a new project that involves groups of groups of groups of groups of…well, you get the idea.
Anyway, the only model that is somewhat "universal" throughout the application is the concept of Users (as they are what determines what privileges any one person has). The problem comes in when you have groups that can "own" other groups. For instance, you can have a "city" chapter that is owned by a "state" chapter that is owned by a "national" chapter, etc. And, each chapter can have their own users when then have rights to all groups below them.
The thing is, though, that no one group is guaranteed to be owned (or used) by another group, so they would need to be independently managed. I can't quite conceptualize what the methodology would be to handle something of this nature. I mean I could probably use some sort of acts_as_nested setup, but I fear even that may get out of hand. Also, as far as the groups themselves are concerned, should I use some kind of inheritance model (given that they would likely share many properties)?
Perhaps I should simply create an individual MVC setup for each group -- although there's still the issue of associating users, etc. Can anyone offer suggestions?
Best
You could create a groups table which self-references. That would keep all your group data in a single table and the magic is done via associations.
Ryan Bates has a railscast that could likely be tweaked to fit your situation. e.g. rather than friendships, having ownerships or something like it.
Edit:
Having only a single parent helps. It appears the plugin acts_as_tree will likely work for the task at hand. Ryan Bates happens to have a railscasts epidsode for that plugin as well.
Objectives
1: Allow groups to have children, parents Solution: acts_as_tree
2: Allow groups to potentially become or remain independent. Solution: acts_as_tree. Simply remove the parent_id and the group would become it's own root node
3: Enforce hierarchy (e.g cities cannot have another city as a parent). Solution: This would likely have to be done via a custom validation
4: Users rights inheritance. I anticipated this particular objective to be the most challenging. Of course, I don't know all the in's and outs of what "rights" means to your application, but I'll some assumptions... you fill in blanks where I'm wrong. Once you have the associations between users and groups (and possible "rights" table). Solution: To determine if rights should apply to current_user for current_group, a) check ownership and if not b) transverse up current_group.ancestors until you get an answer or hit the root.
It sounds like a fun project. I wish you luck with it!
I have created the following tables in my application - roles, permissions and permissions_roles. Roles HABTM permissions, and permissions HABTM roles. I have seen many tutorials on setting up all of the tables/models etc for the 3 tables and defining the relationship, but I haven't been able to find anything on actually maintaining the relationship -- What is the best practice -- set up a third controller/set of views?
I want to be able to create Roles/Permissions independently of the relationship, ie make the assignment later - If I create a new role, I may need to go back and assign existing permissions to it (or vice-versa).
I know there are plenty of plugins that do this sort of thing, but I really want to see if I can learn more by starting from the ground up...
Thanks
Its a little bit dated, but should still work, I shudder at the verbosity of the code but it was one of the first things I did in Rails...
http://blog.wolfman.com/articles/2006/5/20/role-based-authentication-admin-page