For example, I have a password generator in my user registration website. Where should I put the function of generating password?
Put together with UserController?
What is the correct way to put these functions?
I would recommend putting it into a class of its own. For the sake of SRP, your UserModel should do things with a User and only a User. Your UserModel class should not be responsible for generating passwords for new users. Separate it into its own class and call a method on that class during the creation of your new user in your UserModel.
I would put it in my User Model.
Or you could create a Utility class and put it in there.
Related
I have user role based access control. User has many roles.
Each role has access to some controllers, actions and scopes.
I have method can_control?(controller) in User model which check if user have access to specific controller. I have similar method to actions.
Then in view or controller I can make simple logic to hide some information or permit access using:
current_user.can_control?(controller_name)
I wonder if it possible to create method in User model which automatically takes controller_name. I tried to define method in model.
def can_control?
self.permitted_cotrollers.include?(controller_name)
end
But it gives me an error:
undefined local variable or method `controller_name' for #<User:0x007f00e8ceb928>
I understand error, but can find solution or if it possible to have one.
Here is the best solution I can think of : You can access the current controller name in params[:controller] from any controller method.
In User model :
def can_control?(params)
self.permitted_controllers.include?(params[:controller])
end
In any controller :
current_user.can_control?(params)
In your model, you can get the standard associated controller name by using :
"#{self.class.to_s}Controller"
self refers to your model
.class gets its class
.to_s converts its class to a string containing its class name
If you need it written in snake_case instead of CamelCase, use this :
"#{self.class.to_s.tableize}_controller"
.tableize converts the CamelCase name of your model into the snake_case name used in your controller
In ASP.NET, when I want to send a list of model instances to view layer, I convert them into another type (ModelView) by the following code:
var userViewModels = users.select(new {
Name = Name,
UserName = Username
});
I do this because I don't want to send all of my user model data (like password) to view layer. I put this code in my business logic Layer.
I'm using AJAX, and I'm sending my data by JSON protocol. What is the best practice in Ruby on Rails to do a similar action?
In RoR you simply pass models to your views.
Also, view in RoR can directly access (though it's not recommended) models from database. So "hiding" models does not make sense here.
You can consider rails generated scaffold as a close to the best practices.
Controller is used for selecting models from database
View is used for rendering model to the user
Model is the main place to store business logic
Although it is probably unnecessary, as dimakura pointed out, you can select arbitrary attributes when finding by using the select method. Your example would end up looking something like:
#users = User.select(:name, :username)
Actually i am new learner for MVC4, my boss want to change the old asp.net webform to MVC4.
that i have some problems.
one is for each view is that need to create seperate model?
for example, in login page, users just put their name and password and submit.
so in order to receive those name and password, need i create one model for that name and password, namely one auth class with two class member, name and pass.
Or is there any better way to transfer old one to MVC
What you're talking about is a View Model - a class that represents your view / form. Instance of this class will be passed as a parameter to your Login action and will contain username and password. You will usually name your view model class after the view, eg. LoginViewModel.
It is an accepted way to create MVC applications.
In certain Controller I have CRUD methods. In order to access these methods user needs to be logged in. This is why I used [Authorize] attribute for this controller. Now I need additional attribute which would check if item that user wants to view/delete/update belongs to him.
Is it possible and recommended to do this with attribute or you would suggest using check methods inside each method? If you suggest using attribute, could you please provide me some links/instructions?
EDIT:
Ofcourse, if attribute returns false than I don't want to redirect user to login page but show him an error message...
It can be done with a custom Authorize attribute, but it's much cleaner to put the logic inside your controller methods.
The attribute is related to the action being called (the controller class method). On that basis any attribute relating to the user's ownership of the object being manipulated (from your Model) should really be on the entity/class that the user is attempting to manipulate. You'll probably find it easier to validate the user within the Model method rather than using an attribute to achieve this.
In my opinion it is possible, just google for 'Custom Authorize Attribute'.
But maybe it is better to query your database with something like this:
ContextOrSession.Query<Something>.Where(Something.Groups.Intersect(User.Groups).Count>0)
In my asp.net mvc project I store two objects in the session when the user logs in. One is a User object (representing the logged in user) and the other is the Organisation object (representing the user's organisation).
I need one or both of these objects to be available in every action method. What's the most elegant way of dealing with this? At the moment each action takes parameters for each of these objects, with a custom model binder retrieving the objects from session. This at least encapsulates the session access but it's annoying to have the params in every method signature. Is there a better way?
Here's what most of the action methods look like.
public ActionResult Pending(IUser CurrentUser)
{
var users = CurrentUser.GetMyOrgPendingUsers();
return View(users);
}
Since you need to access IUser in almost every action you can have a base controller from where every other controller is derived.
In the base controller put IUser as a member variable and override the
OnActionExecuting() method in the base controller, in which you can put the code to access the session variables.
OnActionExecuting() will be called every time a action is called.
The Controller class has a User property. Have you considered using this rather than designing your own way to track the current user?
I'd rethink using IPrincipal here--it is very handy and allows you to work your way into the rest of the .NET authentication bits very seamlessly.
As for the problem at hand, perhaps the easiest clean course of action would be to wire them into a base controller class as protected properties. Slightly more elegant would be to create a user context class, that takes a reference to Session (or better yet, whatever base interfaces you are using in the session) and expose that class from the controller. The main advantage there is it makes it easier to change the backing store if need be and lets one encapsulate more behavior in general.