Defining a Dynamic Table Name Prefix in Rails - ruby-on-rails

I'm using a Rails application to access a Dynamics NAV Database (today is called Dynamics 365 Business Central). In order to make it multi tenant, they partition the DB using table name prefixes ex: Company 1$Warehouse Entry or Company 2$Warehouse Entry.
I wanted to use a field defined in my User model in order to set the company name that it access.
In order to access the current user in the model I have used the following on application_controller.rb
before_action -> { User.current = current_user }
And then I set a base class where it declares the following instance method:
def self.set_company_name
company = User.current.nav_company ? User.current.nav_company + "$" : "Company 1$"
self.table_name = company + self.table_name
end
I also tried to use instance variables ##company but after reading I saw that table names in rails are cached.
What I have done works, but only if you restart the application. The table name doesn't change in runtime.
How can I make it dynamic? I saw this Question but the answer didn't show how to do this.

I don't know anything about Dynamics 365 and I don't understand why you want to associate two tables to one model, but I have worked with schemas/namespaces in postgresql for example: config.users where config is the schema and users the table name; so you can use it like select * from config.users.
Rails can easily adapt to this struct like you can see here.

Related

Grails secure URL's using get form search

I have a Grails application using Spring Security.
This application is basically a content management system, so it is a CRUD.
My URL's access are basically formatted as follows:
/$controller/$action/$id
This is where encounters problems. That occurs in a controller, for example, to change a user I have the following URL:
/user/update/1
And into the controller I have the following code:
def update(Long id) {
def user = User.get(id);
[user: user]
}
That's the problem. If the user change the (id) directly without checking if the user id in request is correct, anyone can surf the users of my system. Now i have a big problem.
The solution that I thought would be to create a unique hash for each registration system, which would hinder the user to understand that, for example, the ID 1 has the hash 123aabbCCDD, for example.
But i have a lot of registers and many domains in the system, and i don't know if this is the best solution.
I need help to know, for example, using the spring security, I can do this kind of thing.
I tried to find solutions to the issue but I'm not sure by what words to search, so if there is already a question like mine, put the link in comments please.
Thanks.
As Joshua points out, if this is a general problem where you need to limit which users (or which roles) can perform particular actions, the spring-security-acl plugin will help. But that can be tedious to work with because you typically need to model things in a fine-grained way, and you end up with a lot of ACL data in the db.
But if you only want to restrict users to being able to edit themselves, just don't pass the user id. You already know who the user is if the action requires authentication. If that's the case, change the action to something like
def springSecurityService
def update() {
[user: springSecurityService.currentUser]
}
A related workflow that can often avoid using ACLs is allowing a user to edit something that they own, e.g. a CreditCard. Assuming you have static hasMany = [creditCards: CreditCard] in the User class and static belongsTo = [user: User] (or just User user), then you can allow the form to send the credit card id, but you just need to use a modified query, e.g.
def springSecurityService
def update(Long id) {
def user = springSecurityService.currentUser
def card = CreditCard.findByIdAndUser(id, user)
[creditCard: card]
}
The final SQL query will look something like select ... from credit_card where id=? and user_id=?, which has a big security advantage over the SQL for a get() call which would be select ... from credit_card where id=?. A malicious user can still try to send any id they want, but since the where clause checks both the id and the user foreign key, if they're not logged in as the card owner, the finder will return null and you can treat that as a mistake or a hack and not allow access.
Note that the hash approach you described isn't very secure - it's just "security by obscurity". If each user's hash is constant, it's not difficult to find out what a user's hash is and forge a request (e.g. a coworker can just look at another's monitor and see the url in their browser).

Grails relating values from two different domains in a custom view

While I'm experienced with Java, I am a Grails newbie but I am trying to get into it. I set up a basic "School" application containing the following domains:
Student
Class
Attendance
Both the 'Student' and 'Class' domains are scaffolded. Now, I want to create the 'Attendance' domain, and I'm going to need a controller with a custom view. I can do that, I'm just looking to understand (at a high level) the best way to set up the view (let's call it 'attendance.gsp').
The view will contain a dropdown box to select a class. Once a class is selected, I want to populate a table. The first column will contain the list of students in the class, and the second column will contain "Attended?" checkboxes.
I think that I can at least get that far.
I am wondering how to go about relating the checkbox value to the student. Since this class is not scaffolded, no attendance column has been created in the database. Do I need to have anything defined in the Attendance domain? How might you go about doing this? Can anyone recommend a particular example online that is doing something similar?
Thanks!
Something like this:
class Class {
...
static hasMany = [sessionsAttendance: Attendance]
}
class Student {
....
}
class Attendance {
static hasMany = [studentsAttended: Student]
}

django admin foreignKey display troubles

I can't seem to find a solution for the following in the django docs.
So for example, i have a field in Class table called department that points to Department database (foreignKey). If I create a admin interface for Class table called ClassAdmin(admin.ModelAdmin). Then i create an entry for Department class. Now automatically, when i try to create a new Class entry, it will show a dropdown menu for entries in Department. The problem arises when i try to do that, it would show something along the lines of "Department Object" for each entry in the dropdown. I would like a way to define canonical names for each entry for department (Department.name is the field i would like to use).
Does anyone know how to do that?
Thanks a lot!
Implement the __str__ method in your Department model:
def __str__(self):
return self.name

Django List Admin allow sort on Reverse Foreign Key

When Creating your own Admin Class for django.contrib.comments, I want to allow sorting of flagged comments. I can a custom method to the admin class that return comment.flags.count(), but not sure I get the admin to sort by this.
The problem I see is that its CommentFlag model that contains the foreign key to Comment model.
Anybody know a solution with out changing django.contrib.comments?
def queryset(self, request):
qs = super(CommentsAdmin, self).queryset(request)
return qs.extra(select={
'flag_count': 'SELECT COUNT(*) FROM django_comment_flags WHERE django_comment_flags.comment_id = django_comments.id'
},)
def flags(self):
return self.flags.count()
flags.admin_order_field = 'flag_count'
Its a bit messy, but Django complains that flag_count is not an accessor for the Model Comment when you register the admin.

ASP.NET MVC: relationship between models and MembershipUsers

I have a model, Docs, with a guid column, author_id, which should reference a MembershipUser.
I'm using the standard MembershipProvider (I only changed the db name), and of course I haven't a model for MembershipUsers.
I can easily define some methods in class Docs to get MembershipUser for a Doc and all Docs for a MembershipUser, but some things are tricky (listing users, show how many docs each user has); furthermore, I feel I'm using MVC in an odd way: it seems to me that it would be easier if I had a MembershipUsers model...
How can I implement this relationship? Should I implement a model for MembershipUsers?
thanks
update: I realize I wasn't clear at all.
Say I want to list all my users and their docs.
One way to do this is:
ViewModel model = new ViewModel()
{
Users = from MembershipUser user in Membership.GetAllUsers(page, pagesize, out totalusers)
select new UserWithDocs
{
User = user,
Docs = context.Docs.Where(c => c.author_id == (Guid) user.ProviderUserKey)
},
UsersCount = totalusers
};
This works, but generates one separate query for each user.
I could get an array of users' guids and then query for Docs where author_id IN list_of_guids, but then I should manually associate each doc to its author.
What is a better solution?
not sure if i understand you correctly, but you can use the MembershipUser class as your model for users. if you want to reference user to your "doc" model, you can simply add a property "Author" to you model class and when you fetch the model from DB you can get the user as well.
the Membership class contains some static methods to list all users, add/delete users etc.

Resources