multiple django admin instances - django-admin

I need to build one instance of django admin that can be used by multiple companies.
the schema is :
Company1
Branch 1
User 1
User 2
Branch 2
User 3
.......
Company 2
Branch 1
User 4
User 5
Branch 2
User 6
.......
The idea behind this is that user 1 and 2 is able to see (but cannot edit ) user's 3 stuff. Where as users 1 and 2 can see and edit each other's content. All this within the Company1 scope (only).
My question is are there any devs out there who's faced a similar problem and want to share their thoughts on how this can be achieved in dj admin? Any additional packages which can be utilized to extend dj admin functionality in right direction ?
Im aware that this challenges the idea of what was dj admin designed for (no need to caution about this ) ... but since there isn't enough hands to design and build something from a scratch for this project i need to tap into dj admin functionality as much as i can.
All thoughts will greatly be appreciated !

I was in a similar situation, with the added requirement that a user may be in multiple companies, and can "switch". For that purpose I put the "current company" into a session. If in your case you'd just be looking up in the user what they're allowed to see, it should be very easy, by overriding ModelAdmin.queryset, for example:
class CompanyGogglesAdmin(admin.ModelAdmin):
def queryset(self, request):
qs = super(CompanyGoggleAdmin, self).queryset(request)
user_company = request.user.company
return qs.filter(**{ 'company' : user_company })
You could use CompanyGogglesAdmin as a base class for all those models that can be filtered by "company" which gets looked up by the user's company. You could also make that company field configurable, or - like I did - look up the "current" company from a session rather than the user. See also How can I implement a global, implicit filter in Django admin?

Related

app module for permissions assignment on ruby on rails

I'm developing and application with ruby on rails . i have the following models : user, role, option, permission. Depending on the Role of an User i want the menu of the application to display certain options. So an USER has one ROLE, one ROLE has one or many OPTIONS (availables in the menu),one OPTION can be assigned to many Roles . that's why i created a join table called PERMISSION which has rol_id , option_id and status.
SO, in the app, i want to be able to create a new role and check from a list the options this Role can have. But i don't know how to do a form that let me handle all this information and assign the role_id and the option_id the join table needs.
"Best" Solution:
Code it yourself, you should definitely become more familiar with ActiveRecord and be comfortable utilizing relationship tables and the roles one may have, along with writing helper functions like "is_an_admin?" or "is_a_moderator?"
You should also be comfortable with the routes and controllers for adding new users and checking permissions for can POST / UPDATE / PATCH / DELETE entries on your roles database.
Some db like "roles" where you store a user_id and role_level (1 is super_admin, 2 admin, or 3 moderator etc etc) and a user "has_one :role" association?
So my honest recommendation would be to learn it properly, here's some resources:
CULTTT Implementing Roles and Permissions
Association Basics
Easiest Solution
Use a gem, some options:
rolify (https://github.com/RolifyCommunity/rolify)
CanCanCan (https://github.com/CanCanCommunity/cancancan)
Pundit (https://github.com/elabs/pundit)

How to implement Announcements in Ruby on Rails app with per User control of read/viewed

I'd like to implement a site-wide Announcement feature in my Rails app.
Admins would be able to create announcements and define start_date and expiration_date.
I'd also like to know if an User viewed an Announcement, and when he clicked on "dismiss" the Announcement it wouldn't show in the view anymore.
After thinking about it, I am considering creating a Has Many :through model association. Basically a User has_many Announcements through: UserAnnouncements.
So I would create two new models, one fore Announcements (where admins would set the text, start and end date) and one join table (UserAnnouncements) where I would be able to store the information on each User's status regarding that announcement (viewed and dismissed basically).
Would that be a reasonable approach?
My main question right now is in the creation of Announcements. I have 15k users, and it takes considerable time to create the anouncements if I do it like this:
User.find_each do |user|
announcement = Announcement.new
announcement.user = user
announcement.save
end
This takes around 30 seconds to run. What if I had 100k users?
Would a more reasonable approach be create the Announcement model and show it to every User, unless it had a HideAnnouncement model which user_id == current_user ? What would an ActiveRecord like this look like?
Of course you could build it from scratch, but I like the idea to "not waste time on non-core stuff".
That being said, you could give a try to Paul Revere or Starbust gems, both of have as goals display sitewide announcements to users.
As example, after setting Starbust, just add an test announcment with Starburst::Announcement.create(:body => "Our app now features lots of balloons! Enjoy!").
If you want to create your own, sneak peeking their source would also be valuable.

Rails: Multiple "types" of one model through related models?

I have a User model in my app, which I would like to store basic user information, such as email address, first and last name, phone number, etc.
I also have many different types of users in my system, including sales agents, clients, guests, etc.
I would like to be able to use the same User model as a base for all the others, so that I don't have to include all the fields for all the related roles in one model, and can delegate as necessary (cutting down on duplicate database fields as well as providing easy mobility from changing one user of one type to another).
So, what I'd like is this:
User
-- first name
-- last name
-- email
--> is a "client", so
---- client field 1
---- client field 2
---- client field 3
User
-- first name
-- last name
-- email
--> is a "sales agent", so
---- sales agent field 1
---- sales agent field 2
---- sales agent field 3
and so on...
In addition, when a new user signs up, I want that new user to automatically be assigned the role of "client" (I'm talking about database fields here, not authorization, though I hope to eventually include this logic in my user authorization as well). I have a multi-step signup wizard I'm trying to build with wizardly. The first step is easy, since I'm simply calling the fields included in the base User model (such as first_name and email), but the second step is trickier since it should be calling in fields from the associated model (like--per my example above--the model client with fields client_field_1 or client_field_2, as if those fields were part of User).
Does that make sense? Let me know if that wasn't clear at all, and I'll try to explain it in a different way.
Can anyone help me with this? How would I do this?
STI is probably a good fit for your requirements, as suggested by tadman, if you are using ActiveRecord (from Rails 3, it is easy to change ORM). The basic information is available on the AR documentation page, but here is some extra information w.r.t. your target:
Define one model per file. Otherwise there are some initialization troubles. Assuming Client inherits from User all in a single file, Client objects cannot be created as long as a User constructor has not been called once. One file per model circumvents the problem.
All attributes through the hierarchy are defined one-shot in the top class. This is for performance issues, but it seems disturbing many people in blog posts. In short, the Ruby code is object-oriented and encapsulates properly the attributes. The DB contains everything in a single table, with the extra "type" column to distinguish where they belong in the hierarchy. This is only a "trick" to represent inheritance trees in relational databases. We must be aware that the ORM mapping is not straightforward. The image on this site from Martin Fowler may help understand the situation.
In addition, you would like any new user to be a client, where Client inherits from User. To do so, you may simply instantiate any new user as a client. In your controller for creating users:
user = Client.new
# Do something to user
user.save
#=> <Client id: 1, name: "Michael Bolton", email: "mike#bolton.net", created_at: "2010-05-30 03:27:39", updated_at: "2010-05-30 03:27:39">
All the above is still valid with Rails 3 when using ActiveRecords.
It looks like you have two reasonable approaches here, but it will depend on the nuances of your requirements.
You can use Single Table Inheritance (STI) to do what you want, where User is only the base class for others named SalesAgent or Client and so forth. Each of these sub-classes may define their own validations. All you need for this to work is a string column called "type" and ActiveRecord will do the rest:
class User < ActiveRecord::Base
end
class Agent < User
end
The alternative is to have a number of free-form fields where you store various bits of related data and simply interpret them differently at run-time. You may structure it like this:
class User < ActiveRecord::Base
has_one :agent_role,
:dependent => :destroy
end
class AgentRole < ActiveRecord::Base
belongs_to :user
# Represents the agent-specific role fields
end
That would have the advantage of allowing for multiple roles, and if you use has_many, then multiple roles of the same type.

Routing Users to single Models with Rails

I'm creating a Rails app for students and high schools and I'm having some trouble with my User.rb.
I want to have a user model to be used for logging in, but having that user have many roles. The tricky part is that I want users that have a student role to have_one student page, and those that have a role of principal to have_one high_school page.
The students and also nested in the high_school so the entire thing becomes a big mess.
So my question(s): How do I limit a user to only creating one student / high school to represent them? Also how would I nest this student pages inside the highschool without screwing up the user system?
My environment: Rails3 and Ruby 1.9.2dev
Thank you!
Follow up: Would it be possible to put the name of the high_school in the subdomain? That would make the url look like
highschoolname.mysite.com/students/eric-koslow
I'd suggest polymorphic association to user_representations. It'd hold info about which high_school object or which student_page to associate the appropriate user to.
You can made a validation to avoid the multi-creation.

multi level user groups

I'm trying to determine the best structure to approach multi level user groups. Thus far I've created one object called "User" which i assumed could potentially be broken into different levels. Or should I simply create different tables for each user group?
Have a look into Single Table Inheritance..
The short version is that you add a type(string) column to your table and subclass all other models that will use that table from User
Eg:
class SuperUser < User
...
end
I assume you are talking about differnt roles for your users. I am currently using RoleRequirement. It gets the job done fairly easily.
http://code.google.com/p/rolerequirement/
As EmFi suggested, single table inheritance is your best bet. You would need to add the type field to the users table in the database and subclass your User model as below:
class Admin < User
# You probably don't need any methods here.
end
but you would also need to create a before filter. Quite similar to the one which makes sure that the user is logged in, it simply checks the class of your user. This should go in your ApplicationController:
def check_admin
current_user.is_a? Admin
end
There you go, Bob's your uncle, you have rudimentary authorisation.
To promote a user to Admin within rails, just change the type field. Of course, in this way, the user can only hold one access level (which is fine for a lot of applications). If you should want a more complex system, acl9 is quite well equipped for the job. I personally make a habit of using it along with authlogic to form quite a powerful system.

Resources