Accessing userModel in CakePhp 2.2.3 - cakephp-2.2

I'm in the process of upgrading from Cake 1.3 to the latest Cake 2.
I used to access the user model from the App Component as:
$this->Auth->userModel->
However, that field is not there anymore.
Is there an alternative?
I also tried
App::uses('User', 'Model');
$user = new User();
but I get the error
Class 'AppModel' not found
Any alternative way of accessing the user model?

What exactly do you want to do by accessing the User (or any) model?
If in a Controller you can add the Model with the controller's $uses variable:
public $uses = array('User');
You can also access any Model by "jumping over the Model associations". For example if you're in the UsersController and you wish to use the Costume model where User hasMany Costume and Costume is not in the Controller's $uses property, you can do:
$this->User->Costume->find();
The existence of a Model Association is mandatory otherwise it will not work. This is possible since the User model has an internal association to any of it's associated Models.
Since Components wrap Controllers you should be able to do this also there or there should be a reference to the Controller from where you could call: User->Costume->find(); But in the Component you're better of passing data to it from the Controller than trying to call a model from it.

Related

Why is mandatory the "Route" attribute on methods of a custom-routed controller?

Consider a fresh Asp.Net Core 2.1 MVC Web app created via the Visual Studio 2017 template. Now, consider a custom view (MyView) and also a controller (ActualController) so that the project structure looks similar to this picture:
The MyView shows nothing special, and it's off the point. However, the page should appear when the user enters an URL like http://(domain)/desired/myview or also via a hyperlink in the home page:
<a asp-area="" asp-controller="Desired" asp-action="MyView">MyView</a>
Now let's focus on the controller, which is a class named differently from what the routing expects:
[Route("desired")]
public class ActualController : Controller
{
[Route("MyView")] //without this the method won't be called
public IActionResult MyView()
{
return this.View();
}
}
From what I know, by decorating the controller with a Route attribute tells the URL resolver to match this class. However, the mapping works only if I explicitly add a (redundant) Route attribute on the target method/action. If I remove it, the path won't be found, and the server returns a 404-error.
The question is: why should be mandatory to decorate with Route the method, even the action is implicitly defined by the method name (as usual)?
NOTE: is rather simple for me to rename the controller class, but I'd like to know what are the reasons behind this behavior.
You are overriding the default route of [controller]/[action] with [Route("desired")]. Since you don't define an action parameter on controller level, all other routes have to be done explicitly.
Changing the top route parameter to [Route("desired/[action]")] should solve it and the method name will be used as parameter. You can still override single actions if you want to name them differently by adding the [Route("")] attribute to them.
Also see the docs (Token replacement in route templates) for further description on the route parameters

Creating n-tiered with MVC 4 & EF 5

I'm working on creating n-tiered application where I will have two separate project
1) project EF (where it will have all my edmx...)
2) project MVC 4 (internet application.)
In my EF i have, I have my .edmx file and it generate couple of classes with all props as show below (as sample)...
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
public partial class Requester
{
public int Id { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
<//more...........>
}
everything is good so far!!
Back to MVC project
Now I will be creating a new Controller in my MVC project and when I'm trying to create Scaffolding and provide the Controller name and Controller expects a Model so the real question is:
What Model should I be passing here?
should I have the same class that EF created? or should I be creating another Model in my 'Model Folder` (MVC) and bind it? if yes than am I not creating duplicate property if I go ahead and create my same Model in MVC model Folder project?
What I'm trying to do? : Well my purpose of this exercise is to have my Data Access Layer (DAL) totally separate from MVC project.
any thoughts?
I'll suggest to create a view model so you can decorate the properties with view related stuff (i.e. UIHint). Also, this view model will be a reduced version of the class (for example, it can contain just the id of a related object instead of the whole object) making it easier for using as action parameters.
Also, you are talking about objects here, try not to think about "Data".
MVC really needs to be renamed VMVC - ViewModel View Controller.
The models in MVC have nothing to do with EF, Persistence, or your domain. They are a composition of multiple sources of data/settings/things which are represented/required in the View.
So create new View Models for your Views.
Edit:
All examples/tutorials which use EF Code First Models as View Models, are terrible tutorials / examples. They teach you bad practice because in the real world, you would never, and should never use those directly in your view.
The ViewModel is a composition or aggregation of data that's going into your view. For example:
If you had a product detail page, you might get the Product information from the Database, the availability of the product from a Web Service, your Shopping Cart from some Cache.
These would be composed into a ViewModel which represents the View that you're displaying. And rendered.
ViewModels should not be shared between views because if you change a ViewModel you change the meaning of the views that share that View Model.

ASP.NET MVC ViewModel inheritance issue

I have the following ViewModels :
public class MyViewModel
{
public BaseViewModel mySubViewModel;
}
public class ChildViewModel: BaseViewModel
{}
I then create a MyViewModel model, which contains a property of type ChildViewModel. In the View, it is displayed just fine.
Then I hit the save button to submit changes to my Model and I call the following controller:
[HttpPost]
public ActionResult Edit(MyViewModel model)
{
return null;
}
To my surprise, the property mySubViewModel is now of type BaseViewModel instead of ChildViewModel ! I have no idea what's going on here. What am I doing wrong ?
To my surprise, the property mySubViewModel is now of type
BaseViewModel instead of ChildViewModel ! I have no idea what's going
on here. What am I doing wrong ?
You shouldn't be surprised by that. You are doing nothing wrong. This is by design. The default model binder sees that your controller action is taking a MyViewModel argument and is attempting to bind the contents of the POST request to it. The default model binder has absolutely no way of knowing that you might have written some derived classes (such as ChildViewModel in your case) and that you want those derived classes to be used instantiated here. The fact that you have passed this concrete view model instance from your GET action to the view has no influence to the POST action. Think of it in terms of HTTP and what the default model binder sees. Think for example that this POST action could be invoked from some completely different client and not from a form submission. Could be for example an iPhone application performing an HTTP request to the POST action. See, now it makes perfect sense. The default model binder can only see the payload of the POST request and the type you specified as action argument. And that's what he does => it instantiates this types and binds its properties from the POST payload data.
So one possibility is to write a custom model binder that will instantiate the concrete instance of your view model you wish. I have exemplified such a custom model binder at this post. In this example I have included a hidden field inside the form that will contain the concrete type of the view model that we would like to be instantiated and then the custom model binder simply uses this information to create this type at runtime.

Pluralizing rails 3 controller manually

I have a Rails 3 controller which is not pluralized (IphoneUser) - it already has some controller methods, and a model generated.
However I'd like now rather than when it gets too late into the game, to pluralize it.
What's the best way to pluralize this controller without a nightmare of 1-by-1 guess and checks?
You should just need to rename the controller, it's class name, it's views folder, its helper and its functional tests. The only other option is to use the rails generator to destroy it rails destroy and then recreate it named properly. I'd just copy the controller methods and paste them into the new file. rails destroy won't affect your model.

Problem when getting an entity which has been modified in another session

I have a strange problem in my rich client application. Here is some background:
I use one session per view model.
My view models communicate with each others with a Mediator.
I have a management view model where I display a list of my entities. I can edit an entity, which results in the opening of a new view model, which receives the id of the entity to be edited through the mediator.
When the user clicks on the Edit button, my edit view model updates the entity with its own session, and uses the Mediator again, with the edited entity id, to ask the main view model to refresh the list of the entities.
Let's say I change a boolean property called Visible, on the entity.
When I edit the entity, I can see an UPDATE call to NHibernate, updating the entity in the database.
When I come back in the main view model, I do 2 things :
I ask from NHibernate the updated entity
I refresh the list of the entities, to display all the entities, with a custom filter. (Display all the visible entities for example.)
What's weird is that the entity I get from NH in the first instruction has still the old value of the Visible property, but in the list of my visible entities, the entity I've edited is not present...
Here is the two functions of the repository I use to respectively get the entity and get the list of all the visible entities:
public virtual TEntity Get(int id)
{
return Session.Get<TEntity>(id);
}
public IEnumerable<Player> GetAllPlayersSortedByLastName(bool visible = true)
{
return from player in Session.Linq<Player>()
where player.Visible == visible
orderby player.LastName
select player;
}
What's wrong with my code? Why doesn't the entity I get back from NH in my main view model after it has been edited doesn't have the correct values?
Thanks in advance
You keep the ISession alive during the life-time of each ViewModel?
If that is the case - the Entity is present in the MainViewModel's ISession's IdentityMap - so when you ask it to refresh - it just grabs the one in the IdentityMap.
You need to ISession.Evict(updatedEntity) and then run your query again.
This is the whole idea of the 1st level cache in the ISession (to not hit the database if it has been previously loaded.
If you do not want this behaviour and want to bypass the first level cache - you can either open a child session from the session - or run in a IStatelessSession.