I have a model that has several columns I want to present to the interface to update as different pages. My question deals with what is the best rails-y way to organize your routes and controller actions.
For example, a User has a "Profile" and a "Billing Address". Both pages contain columns only from the User model, they are required and one-to-one, and small, so an additional model seems like unnecessary overhead.
It seems like I have to add a GET and a PUT for each different view I want to present, is that right? So instead of just edit/update, I'd need edit_profile/update_profile and edit_billing/update_billing, etc.
Even without a Profile model, I think you still can use ProfileController and views for profile like 'views/update.html.erb', and make it route as '/users/123/profile/'.
In my opinion, we don't need to mapping every view or controller to one model strictly. Rails is based on ROA, but here the "resource" can be more abstract.
Related
I have the following Entities, User and Policy. A User can have multiple policies. I wanted to avoid associations between them, firstly, because the logic behind which policies belong to which user would depend on other things as well, and secondly, to avoid linking aggregate roots by direct reference, so I only store an identifier in the Entity classes.
In order to get a user together with all his attached policies, I decided to create a SQL view, for future reference let's call it user_permission_view, which would look something like this, simplified for brevity
CREATE VIEW "user_permission_view" AS
SELECT * FROM "users"
LEFT OUTER JOIN "permissions"
ON "users"."id" = "permissions"."userId"
The resulting view would have the attributes of both User and Policy. I decided to map this to a Java class called UserPolicyView. However, I'm struggling with how to map the attributes from Policy into a collection field inside the UserPolicyView.
Is it possible to do something like this with JPA? Do I need to define associations to the Policy entity from inside UserPolicyView? How would that affect the generated SQL, if the view already contains a JOIN clause?
Edit:
One possible solution I came up with was to discard the user_permission_view entirely, declare an embeddable PolicyDetails object, create a view containing all user permissions, and use #ElementCollection to specify that view as the source table. Would that work?
declare an embeddable PolicyDetails object, create a view containing all user permissions, and use #ElementCollection to specify that view as the source table. Would that work?
From a technical point of view - yes, it should work (I'll refrain from commenting on whether it's a sound idea from the point of view of domain modelling). You might also want #Immutable, to prevent accidental modification attempts.
As regards your earlier suggestion - you'll only be able to map it as the flattened structure that the view represents. No collection fields, I'm afraid. You can, of course, choose to map only some of the view columns onto properties. But, I suppose that's not what you're after.
My question is about the process of designing an ASP.NET MVC site and specifically about determining what controller classes and action Methods my site should have.
This is what I understand so far about the process of designing an ASP.NET MVC web site:
First, I should use a mock-up tool such as Balsamiq to create a
mock-up, so I know how my site should look. This gives me the views.
Second (or concurrently), I model the objects of my domain.
Given the views and the model, how do I proceed with the controller classes and their action Methods? A controller can call different views, so what's my "factoring" criteria?
So, my question is: Given the views and the model, how do I decide what controllers to have and which action methods each should contain?
Imho, a controller should reflect a specific functional area, dealing with a group of features related to each other. For example, you can have a controller dedicated to user management, where you create and edit users, manage user rights, user profiles, anything related to your users, another controller for product management, where you display available products according to user inputs, manage stocks, suppliers, and such...
With too much controller you end up redirecting all day long, with too few controller it's a mess to maintain.
Of course, when i say"this controller manages that group of features", i don't say "put all your business logic here". Controller's duty is to call the right business method(s) and to pass this data to the right view.
I am trying to figure out how to address this issue:
I have 3 tables with a many-to-many relationship.
Users *-* Roles *-* Permissions
I use a ORM to obtain data from them.
A method of my business layer must return users per permission, so I return objects with this class:
public class UsersPerPermission
{
public User[] {get;set;}
public Permission {get;set;}
}
But this class does not map to any table in the repository, it is something I generate from the existent tables. Where should this class live?
In other words:
Should I have a IRepository.GetUsersPerPermission()? And then that class should live in the repository.
Or should I have a IBusinessLayer.GetUsersPerPermission()? And then I have to invoke the CRUD methods in the repository?
It makes sense to put it in the business layer only, because the repository should just expose CRUD operations to tables... BUT, in order to execute this operation from the Business layer, I would have to execute several independent queries to get the data and create the 'UserPerPermission' class. In the other hand, if I place it in the repository, I can get that information in one shot using grouping.
Thanks!
PS: What is the name of this intermediate objects? 'transformations'?
In DDD, most entities and value objects should correspond to identified domain concepts that are part of your ubiquitous language. I usually try to limit many-to-many relationships and artificial association objects as much as possible. Eric Evans describes a few techniques allowing that in his book. When I have to create an association object, it must have a meaningful name with regard to the domain, basically I never name it Class1ToClass2.
In your scenario, it's even more artificial since your object :
Redundantly models an association that already exists (indirectly) in the original model.
Has a name that doesn't reflect any particular business concept.
Note that this kind of object wouldn't be useless if we were in the presentation or application layer as it could come in handy to have a structure containing exactly what is displayed on the screen (DTO). But I'm talking about the domain layer here, which should be devoid of such composite objects.
So I wouldn't create a UsersPerPermission class in the first place. If what you want is a list of users and User is an aggregate root, just create a GetUsersByPermission() method in UserRepository. It doesn't mean that you can't have a GetUsersByPermission() method in an application service as well, if it matches a use case of your application (a screen that displays the details of one permission and the list of users with that permission).
I agree with guillaume31 that there is no need to introduce a domain object "UsersPerPermission" to support a single use case.
There are two ways you can implement your use case using existing domain classes "User", "Role" and "Permission".
Solution one:
Assume you have: Permission --> Role --> User
Arrow denotes navigability. A Permission has association to a list of Roles and a Role has association to a list of Users.
I would add a method GetPermittedUsers() : List<User> to the Permission class, which is trivial to implement.
Th UI logic will invoke GetPermissions() of PermissionRepository then call GetPermittedUsers() on each Permission.
I assume that you use a ORM framework like hibernate(Nhibernate) and defines the many-to-many relationships correctly. If you defines eager loading for Role and User from Permission, the ORM will generate a query that joins Permission, Role and User tables together and load everything in one go. If you defines lazy loading for Role and User, you will load a list of Permissions in one query when you call PermissionRepository, and then load all associated Roles and Users in another query. Everything is load from database with up to three queries maximum. This is called a 1+n problem which most ORMs handle properly.
Solution two:
Assume you have: User --> Role --> Permission
Arrow denotes navigability. A User has a list of Roles. A role has a list of Permission.
I'd add getUsersByPermissions(List<long> permissionIds) : List<Users> to the UserRepository, and add getPermissions() : List<Permission> to the User class.
The implementation of the UserRepository need to join the User, Role and Permission tables together in a single query and load everything in one go. Again, most ORMs will handle it correctly.
Once you have a list of Users, you can create a method to build a Map<Permission, List<User>> quite easily.
To be honest, I muck like the solution one. I avoid to write a complicate method to convert a List of Users to to a map of Permission and Users, hence I don't need to worry about where to put this method. However solution one may create cyclic relationship between User, Role and Permission classes if you already have navigability in another direction. Some people don't like cyclic relationship. I think the cyclic relationship is acceptable even necessary sometime if you user cases demand it.
In a similar context I used a query method in a domain service that returns something like an
IEnumerable<KeyValuePair<PermissionName, IEnumerable<Username>>>
By using the KeyValuePair<> I avoided to pollute the domain model with an artificial concept (like UsersPerPermition). Moreover such a structure is immutable.
I didn't used a query method on the repository because, in my context, no entity was coupled with the other. So it wasn't matter for any of the repositories.
However this solution is useful for your GUI, if and only if you modelled correctly the identifiers of your entities (in your example both Permissions and Users are entities).
Indeed if they are shared identifiers that belong to the ubiquitous language that your users understand, they will be enough without further descriptions.
Otherwise you are just building a useful DTO for your GUI. It does not belong to the domain thus you should use the simplest possible thing that works (an ADO.NET query? something even simpler?).
Indeed, in my own scenario both the GUI and the domain used such a service (the GUI showing a preview of an elaboration).
In general, the domain model must mirror the domain expert's language, capturing the knowledge relevant to the bounded context. Everything else must be outside the domain (but most of time can be expressed in terms of the domain's value objects).
A core piece of the application I'm working on is allowing the user to explore a complex dataset by progressively add search terms. For example, you might start with a free-text search, then progressively add (or remove) some facetted search terms, move a slider to constrain some dimension of the returned results, etc.
Conceptually, it seems to me that the user is incrementally defining a set of constraints. These constraints are used to search the dataset, and the rendering of the results provides the UI affordances to add further search refinements. So building this in Rails, I'm thinking of having one of the models be the current set of search constraints, and controller actions add to or remove constraint terms from this model.
Assuming this is a sensible approach (which is part of my question!), I'm not sure how to approach this in Rails, since the search is an ephemeral, not persistent, object. I could keep the constraints model in the session store, but it seems rather a complex object to be marshalled into a cookie. On the other hand, I could put store the constraints model in a database, but then I'll have a GC problem as the database fills up with constraint models from previous sessions.
So: how best to build up a complex interaction state in Rails?
Here's some pointers
create a class XxxSearch with accessors for all the search facets: keywords, category, tags, whatever. This class should be ActiveModel compatible, and it's instances are going to be used in conjunction with form_for #xxx_search. This class is not meant for persistence only for temporaryly holding search params and any associated logic. It may even act as a presenter for data: #xxx_search.results, or implement search data validations for each faceting step.
incrementaly resubmit the form via wizard technique, or even ad-hoc data insertion on a large form.
allways submit the search via GET, as such:
the search is bookmarkable
you can chain the params to pagination links easily like: params_for(params[:search].merge(:page => 3))
you need NOT use the session, the data is forwarded via GET params, as such:
can keep using cookie session store
escapes you from a lot of headaches when the last search is persisted and the user expects a new search context (I say this from experience)
I had to solve this problem for several apps so I wrote a small gem with a DSL to describe these searches:
https://github.com/fortytools/forty_facets
I want to apply REST to my Rails 3 application.
I understand the basics but am still a NOOB and would like some help or advice if this is correct.
I have a USER model. However I have three kinds of User, as in they have different roles in the application.
When I create say the Celebrant I need to do other things in the create action that are different then the things I need to to for the Manager which is again different from what I need to do for the Participant.
So I was thinking of creating three resources.
1.Celebrant - new create only
2.Manager -new create only
3.Participant. -new create only
This way I can have the three REST NEW and CREATE actions that are different from each.
Is this the best way to go about this?
A couple of thoughts…
1. DRY
If Celebrant, Manager, and Participant all extend User, then it's best to have 1 controller. Most of the code will be the same between the 3 controllers otherwise.
2. Fat Models, Skinny Controllers
The controllers just pass parameters to models, so really you should only have to call 1 method on the model in the controller, like User.create. This makes it so your controllers don't perform any logic, so you don't need 3 separate controllers.
Check out the inherited_resources gem to pretty much remove all code from your controllers.
Doing it like this, you handle what happens before/after create in each of your User model subclasses.
3. Using a Role model instead of User subclasses
I ran into your exact problem before. I started with 3 user classes. But I quickly wanted to do more with the roles, add more, blur the lines, etc. By having 1 User model which has_many :roles (there's role plugins out there), you can handle all your custom logic in your save callbacks in the user model based on roles. Now your controller is lean, and you don't have to manage 3 classes.
Hope that helps.