How do I move terms from one vocabulary to another in Drupal 7 without losing the node reference? - mysql

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.

Related

Good architecture for app with variable list of attributes

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

How to structure table Activities in a database?

I have a site written in cakephp with a mysql database.
Into my site I want to track the activities of every users, for example (like this site) if a user insert a product I want to put this activity into my database.
I have 2 ways:
1) One table called Activities with:
- id
- user_id
- title
- text
- type (the type of activity: comment, post edit)
2) more table differenced by activities
- table activities_comment
- table activities_post
- table activities_badges
The problem is when I go to the page activities of a user I can have different type of activities and I don't know which of this solution is better because a comment has a title and a comment, a post has only a text, a badge has an external id to its table (for example) ecc...
Help me please
I'm not familiar with CakePHP, but from purely database perspective your data model should probably look similar to this:
The symbol denotes category (aka. inheritance, subclass, subtype, generalization hierarchy etc.). Take a look at "Subtype Relationships" in ERwin Methods Guide for more info.
There are generally 3 strategies for implementing the category:
All types in single table. This requires a lot of NULLs and requires CHECKs to make sure separate subtypes are not inappropriately "intermingled".
All concrete types in separate tables (excluding the base, which is ACTIVITY in your case), which means common fields and relationships must be repeated in all child tables.
All types in separate tables (including the base). This implementation requires a little more JOINing, but is flexible and clean. It should be your default, unless there are strong reasons against it.

CakePHP alternative to Class Table Inheritance?

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!

How to store hierarchical information into a database?

I have the following information that should be retrieved by using several dependent select fields on a web form:
Users will be able to add new categories.
Food
- Fruits
- Tropical
- Pineapples
- Pineapples - Brazil
- Pineapples - Hawaii
- Coconuts
- Continental
- Orange
- Fish
....
This data should come from a database.
I realize that creating a table for each category here presented is not a good schema perhaps, so I would to ask, if is there any standard way to deal with this?
I'm also aware of this schema example:
Managing Hierarchical Data in MySQL
Is there any other (perhaps more intuitive way) to store this type of information ?
The link you provided describes the two standard ways for storing this type of information:
Adjacency List
Nested Sets
One issue your question didn't raise is whether all fruits have the same attributes or not.
If all fruits have the same attributes, then the answer that tells you to look at the link you provided and read about adjacency lists and nested sets is correct.
If new fruits can have new attributes, then a user that can add a new fruit can also add a new attribute. This can turn into a mess, real easily. If two users invent the same attribute, but give it a different name, that might be a problem. If two users invent different attributes, but give them the same name, that's another problem.
You might just as well say that, conceptually, each user has their own database, and no meaningful queries can be made that combine data from different users. Problem is, the mission of the database almost always includes, sooner or later, bringing together all the data from the different users.
That's where you face a nearly impossible data management issue.
Kawu gave you the answer.... a recursive relation (the table will be be related to itself) aka Pig's Ear relation.
You example shows a parent with several children, but you didn't say if an item can belong to more that one parent. Can an orange be in 'Tropical' and in 'Citrus'?
Each row has an id and a parent_id with the parent_id pointing to the id of another row.
id=1 name='Fruits' parent_id=0
id=2 name='Citrus' parent_id=1
id=3 name='Bitter Lemon' parent_id=2
id=4 name='Pink Grapefruit' parent_id=2
Here are some examples of schemas using this type of relation to provide unlimited parent-child relations:
Data model for product categories
Data model for organizations and people

In web development, what are "term", "taxonomy terms" and "vocabulary"?

I need to create 2 more tables with purpose: one table will store tags and categories data (categories can have a hierarchy but tags are not) and another table store relationship between tag, category and content. But I so confused about name of those 2 tables. I'm really a newbie in web development. After googling a bit, I found some words like term, taxonomy terms and vocabulary from drupal and wordpress. But I have no idea what they mean. Can you explain those words and help me give a name for my two tables. Of course if those tables are not well design for my purpose please guide me too.
content{
content_id
...
}
table_A{
type (tag, category, ...)
name
parent_id
}
table_B{
table_A_id
content_id
}
With relevance to wordpress, those words are indeed confusing. If you are using wordpress to build a site, you shouldn't need to worry about the database tables for storing taxonomies and terms as it has built in methods to handle all that.
You'll notice when you're in the wordpress admin panel editing a page or post that there is by default a box on the right which calls itself "Categories" and allows you to create new categories. Once one is created, you can add your posts or pages to any "Categories" you've created. I'm sure you understand that already.
As wordpress releases were built, people started asking for more customizing control over categorizing their content. So developers added "custom taxonomies" to wordpress. For clarity, I should mention that "Categories" is the name of a default "Taxonomy" built into wordpress.
A taxonomy is a group of terms. So when you create a "Category" in the right hand box of the admin panel (say "news" for example), you are creating a "term" named "news" which belongs to the "Categories" taxonomy.
This allows a developer to define their own taxonomy (let's say "products") and associate it with pages, posts or any other "post type". So if it's associated with just plain regular "posts" in the admin panel. A box exactly like the existing "categories" box would show up upoon editing but would call itself "products" instead. Anything added to that list would be a term under the "products" taxonomy.
Hope this clarifies things a bit for using wordpress. These terms can be used differently in different contexts so nothing I've said necessarily applies to anything outside of the wordpress package. Unfortunately there is often no universal "web development" meaning for a given word you may see thrown around in discussion.
Taxonomy, last time ago, means categorize life organisms. Similarly, in computer engineering, taxonomy means categorize terms, can be substantive(three, car, cat), verbs(go, be, do). Taxonomy and terms can be mens anything, but the concept is a data structure and hierarchy