how to save class extend in grails?
example i have class user and administrator
class User {
String name
String password
}
class Administrator extends User {
String authoritySelected
}
example in class User i have save "user1",
and then i want to change user1 from class user to class administrator and update authoritySelected
def update(){
def user1 = User.get("user1")
user1.authoritySelected
user1.save(flush:true)
}
and get error :
No such property: authoritySelected for class:User
so, how to save authoritySelected in class User and change that to class Administrator? thanks.
Speaking about the syntax, the code you wrote has no sense. Speaking about design, neither.
May I suggest you to study a bit a OOP before attempting doing this kind of stuff? :)
But let's face the problem you submitted.
First suggestion: don't implement the security system for your application, there's a lot of stuff that can do it for you. One above all: Spring Security plugin.
Second: the code you wrote doesn't work because extending a class is a way to make another class 'son' of the parent. In you example, Administrator is a son of User.
def update(){
def user1 = User.get("user1") // I don't get how this should work, but I'll leave it like this in this example
user1.authoritySelected // you're trying to GET the value a property that doesn't exist in the User class, you should SET something here
user1.save(flush:true)
}
If you want your User to change role, the easiest think is to think at the role not as another class, instead it should be an attribute of the User, so you can change it. Once the instance of a class is created, you can't change it (probably this is not totally true, but you shouldn't).
OK, some code:
class User {
String name
String password
String authority // a property of the class you can change
}
def update(){
def user1 = User.get("user1")
user1.authority = 'Administrator' // change the property on the instance you retrieved
user1.save() // save the instance itself
}
This is still not a good design solution to me, I'm just trying to make you able to see what you're doing wrong.
When you say "and then i want to change user1 from class user to class administrator", what exactly are you trying to do?
You are trying to access a property of an object that doesn't exist in that object. Downcasting simply doesn't work like that. You should instantiate an object of type Administrator in order to save one of its properties after.
if you want to create a USER you have to create an USER's instance, for example:
User u = new User(name: "xpto", password: "xptopass").save(flush:true)
An Administrator is a USER too, but with one more data, the authoritySelected, so if the Administrator extends User, he have the same data like a User too.
Administrator a = new Administrator(name: "xpto", password: "xptopPass", authoritySelected: "ADMIN").save(flush:true)
Attention, Object.get(X) methods needs an ID (Long), "X" would be a Long value, not a String.
http://grails.org/doc/2.3.x/ref/Domain%20Classes/get.html
Related
In my Ionic 5 project, I have created a custom component and passing the data from a Page.
HomePage HTML:
<app-userItem [inUser]="user (outSync)="syncUser($event)"></app-userItem>
Where user is.
let user = {
Name: 'Test User',
Age: 23
}
Now I want if inside component UserItem I change the value of Age, it should be synced back in the Homepage user variable. It is not happening automatically.
To Achieve this I am using the outSync event emit method for now. My question is as I am using [] to pass value of parameter inUser, shouldn't the user variable be in sync from both sides?
Now I want if inside component UserItem I change the value of Age, it should be synced back in the Homepage user variable. It is not happening automatically.
I think the reason why it's not happening automatically is because Angular compares the object identity to see if something has changed, but in your case, user === user is true even after changing user.age because the instance is still the same.
It doesn't mean the object is not being updated – it's just that Angular doesn't know that because the instance of the object is the same so as far as Angular knows, nothing have been changed.
A better approach would be if the UserItemComponent only presents the data, but doesn't change it directly (which would make it a dumb or presentational component).
For example, if that component could change both the name and the age properties, it'd be better if it just notifies the parent that those properties should be changed, and it's the parent who updates the user.
<app-userItem
[inUser]="user
(updateAge)="updateAge($event)"
(updateName)="updateName($event)"
></app-userItem>
And then the parent component would modify the data, creating a new instance of the object so that the child receives the update:
public updateAge(newAge: number): void {
this.user = {
...this.user,
age: newAge
};
}
I'm having difficulties in two areas:
1) When a user successfully logs into their account using phone auth in Firestore, I take them to an "Edit profile" page so they can add their profile information. I get an error saying that I can't add data to a null user class or add data to a class within a class.
I currently have my user class setup something like the following:
class User {
String points;
Name name;
User({this.points, this.name});
}
class Name {
String firstName;
String lastName;
Name({this.firstName, this.lastName})
}
As you can see, I have a class within a class and when I try to add a value, it says I can't. I've tried doing it like
_bloc.user.name.firstName = value
And I've tried like
Name newName = Name();
newName.first = value.
The second one seems to work but it doesn't seem right. I'm hoping you could help me understand how to properly approach adding data for new users when I have a class within a class.
The second issue is understanding how to properly use the Places API. I'm currently learning from the below repo, but it's outdated and there's a couple lines I can't seem to figure out how to change. I also can't seem to find an updated tutorial since the October app crashing update.
https://github.com/alfianlosari/flutter_placez
Thanks in advance for your help!
Just a question to poll how you guys would tackle this in Laravel:
I have a user preferences page defined in UserController.php which creates the view at user/preferences.blade.php.
Administrators should of course be able to edit the user's preferences and have some extra administrative fields shown to be changed. Furthermore I'd like to collect all admin functionality concerning users in a separate controller called AdminUserController.php
I'm thinking of some possibilities to achieve this functionality:
Create an additional view (e.g. admin/user/preferences.blade.php) and almost replicate the GET and POST methods of UserController.php to accommodate the extra fields. However this seems to me like a lot of redundant code...
Convert the GET and POST methods of UserController.php to something like this:
public function postPreferences($user = NULL, $admin = FALSE) {
if (!isset($user)) $user = Auth::user();
// Process regular fields.
if ($admin) {
// Process admin fields.
}
}
Add the admin fields to user/preference.blade.php and conditionally show them if $admin is TRUE, and then call the UserController's methods from within AdminUserController, e.g.:
public function postPreferences($user) {
return (new UserController)->postPreferences($user, TRUE);
}
However, there are some drawbacks. First: controllers shouldn't call each other... Second: this only works for the POST method. Upon requesting the GET method from UserController an exception is being thrown...
I'm curious about how you would tackle this!
Thanks.
This is mostly a question of preference, but I really suggest you to completely separate all that is possible here. Administration is a process that is very sensitive and not in any way should it be possible, that a normal user will be able to see it under any circumstance.
I believe that we all are humans and we make mistakes more or less often, that's why we need to make sure that our mistakes in not assigning right value to the right variable or making a type of = instead of == not to ruin business logic.
I think you should make a separate view and a separate controller for user self management and administration and never tie them up. If you want to keep your code DRY as much as possible, you may extend your user controller and model from your admin controller and model, but not the other way around. That's just my 2 cents, it all depends on what type of application you are working on and what the stakes are.
<?php
class AdminController extends UserController
{
public function __construct(AdminModel $model)
{
// Use dependency injection
$this->model = $model;
}
// In the original UserController class:
public function postPreferences($user) {
$this->model->edit($user, Input::all());
// you may do it this way so your user only saves user data and
// you admin model saves all the data including administrative
}
// ...
}
I am using a membership provider that specifies required fields in user such as username and password. You can then inherit this user class to create your own user with any other fields you need.
I added an account like so
public Account AdminAccount { get; set; }
when i now get my user using the membershipprovider it does this:
return _context.Set<TUser>().SingleOrDefault(u => u.Username == username);
The class definition for this membership class looks like so
public class FlexMembershipUserStore<TUser>
: IFlexUserStore
where TUser: class, IFlexMembershipUser, new()
So I send in my user class when creating it, and the class knows about Tuser as a IFlexMembershipUser.
However IFlexMembershipUser does not have my AdminAccount property, only my class that inherits from IFlexMembershipUser has that.
And so when I fetch my user even tho he in the database has a field called AdminAccount_Id which is set correctly I only get AdminAccount to be null.
I see the problem of course with the membership only seeing IFlexMembershipUser and my property not existing on that class but other scalar values are read in properly.
Is there anything I can do about it.
In this particular case I can make the account keep track of it's admins as a user list instead. So I can solve this that way but I am still curious if this can be solved otherwise.
The issue here is that EF only loads things you tell it to for performance reasons. You have two options for loading the remote nav properties, Eager loading (my prefered) or lazy loading.
With Eager loading you tell EF at query time you are interested in the specific nav property and it will go ahead and load it for you. To do this:
using System.Data.Entity;
....
_context.Set<TUser>().Include(u=>u.AdminAccount).SingleOrDefault(u => u.Username == username);
Hey guys, I'm starting with Zend, and trying to understand the way it works (getting there), and with Acl classes, people seem to declare all the roles and resources in one file. Now to me this seems a bit of a waste of system resources if the person is only logging in as a basic user, or even just a guest/visitor to the site. So I was thinking is it possible to have different classes which set the roles dependant on the role/resource of the current user.
My current idea is to use switch/case on the role in the bootstrap, and load individual Acl classes based on the role name (for example sake, 'visitor' => 'Model_VisitorAcl', 'users' => 'Model_UserAcl' and 'admin' => 'Model_AdminAcl'), each with a corresponding class file. Then within the class files do something for each one. This is working, and currently I could define all my 'admin' acls in one (backtracking through the rights heirarchy of admin-user-visitor), then in 'user' have 'user'-'visitor' roles and resources.
However this doesn't seem the best way, as if I wanted to change the role permissions for 'user' I'd need to change it for 'user' and 'admin'. This is obv not a problem with 2 roles, but on bigger systems it obviously is.
So I tried something like
class Model_AdminAcl extends Zend_Acl{
function __construct(){
$d = new Model_UserAcl();
//defining the admin role and permissions, with inheritance from the roles
//set in Model_UserAcl
}
}
To try and get the Model_UserAcl construct function to run, thus setting the role 'user', however this does not seem to work, throwing "Uncaught exception 'Zend_Acl_Role_Registry_Exception' with message 'Parent Role id 'users' does not exist'"
error.
So whats the next step? Having individual include files for each module, and have the required classes include them as needed?
Or am I just making mountain out of molehills with this issue?
Thanks,
Psy
Ok, solved this, not sure why I didn't think to try this in the first place (Friday brain frazzle I think)
I just put the contents of the constructor into its own function, and then called that function in the constructor, and make the classes inherit from the class below it.
//Model/VisitorAcl.php
class Model_VisitorAcl extends Zend_Acl{
function __construct(){
$this->addVisitorRules();
}
function addVisitorRules(){
//adding the role and permissions
}
}
//Model/UserAcl.php
class Model_UserAcl extends Model_VisitorAcl{
function __construct(){
$this->addVisitorRules();
$this->addUserRules();
}
function addUserRules(){
//adding the role and permissions
}
}
//Model/AdminAcl.php
class Model_AdminAcl extends Model_AdminAcl{
function __construct(){
$this->addVisitorRules();
$this->addUserRules();
$this->addAdminRules();
}
function addAdminRules(){
//adding the role and permissions
}
}
If this is not the way I should go about it, then by all means please let me know.
Psy