I have two Entities : Category and Product with a many to many relationship.
How can I prevent the UI Programmer to add a Category when he wants to add a Product? In fact I want the UI programmmer to only add Products and set predefined Categories and not to be able to add new Categories for the Product.
You must code the logic in your layer exposed to UI programmer and ensure that only product is created. That means you must wrap EF completely in your layer and do not expose it to upper layers. If you expose EF context to upper layer you are giving it all permissions.
Related
I'm currently working on a Publishing Bounded Context. The main players in this context are Product and Listing.
Product : can be listed in multiple marketplaces. One Product Many Listing.
Listing : can have many products because some marketplace support variation listing. One Listing Many Product.
Based on the above I have a Many-To-Many relationship between Listing and Product.
I created an aggregate for both. The Product aggregate which contains listings and the Listing Aggregate which contains products.
Is it acceptable to have Listing defined in both aggregates or should I define Listing once to be used in both aggregates?
First Listing would be within the product aggregate because the product AR has a factory method that enforces rules when creating Listing(such as avoid duplicate listing in same marketplace and ensure we have stock qty for listing)
Second Listing would be an aggregate root which can contains info from many Product needed at the moment of publishing. This way I can create method on Listing to map it to a schema definition provided by different marketplaces (such as Ebay and Amazon). Also I want to be able to persist Listing independently from Listings within the same Product.
Do the two aggregates have too much overlap with duplicate definitions ? Is this to be expected within one bounded context?
Also how can I keep the duplicate representation of Listing synchronize with each other?
First Listing would be within the product aggregate because the product AR has a factory method that enforces rules when creating Listing(such as avoid duplicate listing in same marketplace and ensure we have stock qty for listing)
Should a product know its own stock, its own marketplaces, its own listings and create listings too? This is too much responsibility for an entity! I would suggest to let a ListingFactory check the stock and the marketplces with other services or repositories that hold this information.
Is it acceptable to have Listing defined in both aggregates or should I define Listing once to be used in both aggregates? Also how can I keep the duplicate representation of Listing synchronize with each other?
Avoid cyclic dependency between Product and Listing and a mess by maintaining a single list (have a look at this question for a similar tangle: How to design many-to-many relationships on deletion?). Seems to me you should have an aggregate of marketplaces, which contains your listings. You could setup a marketplace service or repository that gets all Listings if you need to access all listings based on a product (like in the ListingFactory I proposed).
Do the two aggregates have too much overlap with duplicate definitions ?
Your definition of product "can be listed in multiple marketplaces" is not a very satisfying definition, because after reading this definition the question still remains: What is it then that can be listed? At its core a product can be defined without knowledge of listings, but within this context it probably would still be better to explicitly name the relationship. Since a (product) listing can not be defined without a product, but a product can be defined without a listing. They need not be duplicates. I would expect your product to be completely listing-unaware, but related to listings within the context.
Is this to be expected within one bounded context?
All definitions build on each other, so within any context you can expect overlap, duplication, synonyms, extensions, near similarity, cross-referencing, different types of relationships, etc. It requires quite a bit of investigatory consciousness to separate the primary from the secondary, the predicates from the subjects and objects, the nucleus from the membrane. However, this is also what makes it so much fun :)
definition of word: "A single distinct meaningful element of speech or writing, used with others (or sometimes alone) to form a sentence.."
definition of sentence: "A set of words that is complete in itself, typically containing a subject and predicate, conveying a statement, question, exclamation.."
We are breaking a large asp.net web forms app into chunks and one of the pieces will be rebuilt using asp.net mvc. There are 2 primary types of orders (lets say types A and B). Each order has secondary types (lets say A1,A2, B1, B2, etc.) and each order has attributes. Type A* orders share almost all of the attributes and Type B* orders share half of all the attributes. From the order history we found most of the orders placed were of Type A. The current design uses user controls for the order form for each secondary order type so there is user control for A1, another for A2, etc. The attributes are fields in these user controls.
As part of the redesign we wanted to see if we can get away from user controls and instead generate the order form with the necessary attributes dynamically while keeping the app lightweight and also be able to add a new secondary order type with minimal effort.
Design 1: Create a table with all possible attributes and map them to each secondary type and turn on/off attributes? It could get very granular and include information about how an attribute should be rendered.
Pros: Adding secondary order type is easy, just need to add mapping for new order type.
Cons: Adding new attributes will requires changes to mapping table and perhaps all the layers. May need an admin section to manage mappings.
Design 2: Use jquery templates to replace user controls, send up json to the server.
Pros: Easy to add new form for a new secondary order type.
Cons: some logic may have to go into the templates (views)
Any advice on which one of these is a good design? Is there a better way?
Thanks.
Your database design has nothing to do with ASP.Net or JQuery. You need to worry about building a solid data model.
Table Inheritance and a good ORM will help here.
http://martinfowler.com/eaaCatalog/singleTableInheritance.html
https://community.jboss.org/wiki/NHibernateForNET
I've inherited a site with a very big hierarchical taxonomy:
Vocabulary name: categories
--term: company name
---- many child terms
-- term: country
---- many child terms
-- term: issue
---- many child terms
I realized it would be easier to create Search facets and Views with appropriate content if I set up each of these parent terms as their own Vocabularies:
company
country
issue
So I created the new Vocabularies and used Taxonomy Manager to shift all the sub-terms to their new vocabularies. I then updated the Article node content type to be associated with these 3 vocabularies.
Unfortunately I also noticed the term relationship between the Article nodes (all 4,000 of them) and the Terms was now lost in the display. I thought this relationship would have been maintained by the Taxonomy Manager module.
I've been searching for a way to update the vocabulary references for the Article nodes, but I'm still not sure how the vocabulary is associated with the node. I see new field_data_field_vocabulary-machine-name tables are created for each new vocabulary - and this is where the termID and node/entity ID are associated. However I don't know how to update the Vocabulary for a node automatically when I move a term from one vocabulary to another.
I've recently move this site from Drupal 6 to 7 so it doesn't help that there are a lot of dead tables from D6 cluttering up the database.
--
I've now set up a new standard D7 install and am looking at the db default tables trying to figure out where the Vocabulary/Node relationship gets defined. On my old db the TermIDs still seem to be correctly associated with the Nodes in the Node table... but I don't see where the VocabularyID/TermID/NodeIDs are stored/updated.
Please try this module: http://drupal.org/project/taxonomy_manager
This module provides a powerful interface for managing taxonomies. A vocabulary gets displayed in a dynamic tree view, where parent terms can be expanded to list their nested child terms or can be collapsed.
The Taxonomy Manager has following operations and key features:
dynamic treeview
mass deleting
mass adding of new terms
moving of terms in hierarchies
merging of terms (using the Term merge module in 7.x)
fast weight changing with up and down arrows (and AJAX saving)
AJAX powered term editing form
simple search interface
CSV Export of terms
i18n support for multilingual vocabularies (per language terms)
Double Tree interface for moving terms in hierarchies, adding new translations and switching terms between different vocabularies
For using the Taxonomy Manager you should have JavaScript and automatically load of images enabled in your browser.
-> but I'm still not sure how the vocabulary is associated with the node
In Drupal 7 taxonomy references are done very differently than they were in Drupal 6. If you want to associate a vocabulary with a node in Drupal 7, you have to add that term as a field on the content type:
Go to admin/structure/types/manage/article/fields where you can add/delete/modify fields for your article content type
Add a new field, name it whatever you'd like, and make sure you choose type 'Term reference' from the drop-down
Make sure you choose the correct vocabulary for it to pull from
Repeat this step (add two more fields) for the remaining two vocabularies.
Go to admin/structure/types/manage/article/display and modify whether you want these new fields to be displayed on the node or to be hidden
=============== Addition ==================
In Drupal 7, since terms are just like any other field, you'll see the relationship in the DB (of course -- only once you add the appropriate term reference field to your content type) in a newly created table that stores the information about that field. For example, it may be called field_data_field_tags for the standard 'tags' vocabulary that comes with Drupal 7 by default. In that table you'll see the columns entity_id (that's the node's id) and field_tags_id (that's the term's id), but that column may have a different name for your specific term. So you would have three separate tables for each of your terms' relationships to your node, since they would be three separate fields in Drupal 7.
Does that help a little more?
I think you should :
Create new vocabularies
Add fields with term reference to new vocabularies
After you connect content type with new vocabularies, then you
should move terms to new locations
I tested and it works for me with this order.
I want to create a Class Table Inheritance model in CakePHP.
I would like to have a Model called something like ProductBase with the table product_bases to hold all the base information every product should have, like upc, price, etc.
Then have specific product type models extend that. For example ProductRing with the table product_rings to hold specific ring information like ring_size, center_stone, etc.
Then if I retrieve data directly from the ProductBase model, have it pull all types:
// pull all product types
$this->ProductBase->find('all');
Or find specific types only:
// pull only Rings or descendants of the Ring type.
$this->ProductRing->find('all');
Is anything like this possible in CakePHP? If not, what should I be doing instead?
What is the proper Cake way of doing something like this?
I worked with CakePHP for two years, and found no satisfactory solution for this, so one day I wrote a solution for it. I built a new kind of ORM that work as a plugin on top of CakePHP 2.x. I called it "Cream".
It works similar to the entities of CakePHP 3.0, but in addition supports multi table inheritance. It also supports very convenient data structure browsing (lazy loading) and is very easy to configure. In my opinion it is more powerful than what CakePHP 3.0 offers right now. Data structure browsing works as follows:
$entity = new Entity('SomeModel', $somePrimaryKeyValue);
$foo = $entity->RelatedModel()->YetAnotherRelatedModel()->someProperty();
However, it is important to notice, that in Cream, each entity object is a compund of a series of models and primary key values that are merged together. At least in the case where model inheritance is used. Such a compound looks like:
[<'SomeConcreteModel', primaryKeyValueA>, <'IntermediaryModel', primaryKeyValueB>, <'BaseModel', primaryKeyValueC>]
It is important to notice that you can pick up this entity by any of the given model/primaryKeyValue combinations. They all refer to the same entity.
Using this you can also solve your problem. You can use standard CakePHP find methods to find all primary key values you want from the base model, or you can use the find methods models that inherit from it, and then go along and create the entities.
You set up the chain of inheritance/extension by simply writing in your model class:
public $extends = 'YourBaseModel';
In addition you also needs to setup an ordinary CakePHP relationship between the models (hasOne or belongsTo). It works just like in normal OOP, with a chain of models that inherit from their bases. If you just use vanilla CakePHP you will just notice that these models are related, but when you start using the Cream interface, all entities merge model/primaryKeyValue pairs into one single object.
Within my github repository there is a powerpoint file that explain most of the basic features.
https://github.com/erobwen/Cream
Perhaps I should fork the CakePHP project and make a pull request, but for now It is a separate repository. Please feel free to comment or participate in developing "Cream".
Also, for those suggesting that it is best to just "work with the CakePHP flow as intended" I would argue the following. Common estimates suggest that C programs are 2.5 times bigger than the C++ counterpart. Given that the only feature that separates these languages is the OOP with inheritance etc, we can deduce that the lack of proper OOP with inheritance etc requires the programmer to do 150% additional work with repetition code etc. Therefore I would argue that a proper model inheritance mechanism in CakePHP is very much needed. Cream is an attempt at this.
You are referring to an ARC relationship (or at least a variation of it). Cake does not handle these types of relationships on the fly. This means you will have to implement your own logic to handle this.
The other option is to categorize the products. If the product can fit into multiple categories, then you will want a HABTM categories for each product. Otherwise, you can use a category column. I suspect it will be a HABTM you are looking for.
PRODUCTS: The table that holds the
products.
CATEGORIES: The list of categories
any given product can belong to.
CATEGORIES_PRODUCTS: The link between
each product and their various
categories.
TYPE: This is the flag that will
define the type of product (i.e.
ring, shoe, pants, etc.)
Then when you want ALL products, you query the products table. When you want a slice of the products (i.e. Rings) you select all the products that belongs to the RING category.
Now, we need to address the information about the product. For example, not all information will apply to every product. There are a number of ways to do this.
You can build multiple tables to
hold the product information. When
you pull a product of a given type,
you pull its companion information
from the table.
Store the information in a text
field as serialized data. All of the
information can be defined in a
settings var and then you can use
the serialized data to map to the
information.
I hope this helps. Happy coding!
I have a User model that can hold 1-n UserGroup models, each of which holds data about the user's relationship with a specific group (for example, if they're the admin of the group, when they joined the group, etc.).
I'd like to provide some helper methods like isGroupUser() and isGroupAdmin() that work on the entire set of UserGroup models stored in a User model. Right now these methods are in the User model, but they just about double the size of the model.
Does it make sense to push the code that works on the UserGroup models into its own class? So then the User model would contain a single instance of this "interface" class, which would also now contain the UserGroup models to work on. I feel like this keeps related code nicely separated and the User model from becoming overwhelming.
Also, is there a design pattern for this sort of thing? It seems like a class that works on a collection of other objects would be pretty common.
Thanks for your insight!
Iterator: Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation. [GoF, p257]
Visitor: Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates. [GoF, p331]
If you are new to design patterns a quick overview is available at http://www.vincehuston.org/dp/
I suppose the other big benefit of doing it that way pushes all of this UserAccessControl or UserPermissions into a nice reusable setting or object.