Возможны ли эти отношения в ORM CF9?Как? - PullRequest
2 голосов
/ 01 февраля 2012

Во-первых, соответствующие биты структуры таблицы:

contact
    -contactID
    -email

data
    -value
    -contactID
    -definitionID

definition
    -definitionID
    -name

Каждая запись в таблице contact представляет один контакт вместе с их адресом электронной почты.

Каждая запись в таблице definition представляет определение пользовательского поля данных.Например, в definition может быть пять записей - Организация, Почтовый индекс, Комментарии, Адрес, Телефон.В дополнение к именам полей он также определяет соответствующие метаданные о полях.

Каждая запись в таблице data содержит значение поля пользовательских данных, связанное с контактом.Его определение взято из таблицы definition.

Чтобы уточнить, если бы я хотел сгенерировать таблицу контактов вместе с данными их настраиваемых полей, он мог бы выглядеть так:

| E-Mail            | Organization | Zip Code | Comments                         | Address       | Phone    |
-------------------------------------------------------------------------------------------------------------
| sean@example.com  | ACME         | 12345    | Cool guy!                        | 123 Test St   | 555-5555 |
| sean2@example.com | SomeCo.      | 54321    | Doesn't know anything about ORM! | 321 Test Blvd | 444-4444 |

Преимущество этой системы в том, что она может масштабироваться настолько, насколько мне нужно, и ее легко настраивать.Ущерб в том, что я понятия не имею, как определить отношения:)

Я пытался определить contact:data как 1:M и definition:data как 1:M, но результаты кажутся немного странными:С двумя контактами и одним определением добавление строки к данным для каждого контакта и затем вызов entityLoad( 'Contact' ) приводит к интересным отношениям.Это выглядит так (просто собираюсь использовать некоторую нотацию псевдоструктуры, потому что ее достаточно легко набирать и, я надеюсь, читать):

{
    contact: {
        email: 'sean@example.com',
        data: {
            value: 'ACME',
            definition: {
                name: 'Organization',
                data: {
                    value: 'SomeCo.',
                    contact: {
                        email: 'sean2@example.com'
                }
            }
        }
    }
}

Похоже, что это создает косвенную связь между contactи definition на основе отношения таблицы data к обеим таблицам.Как вы можете себе представить, увеличение количества контактов и настраиваемых полей только усугубляет проблему.

Возможен ли такой тип отношений с использованием ORM CF9?Как я могу это сделать?

Заранее спасибо!

РЕДАКТИРОВАТЬ: Забыл указать - я использую MySQL, если это важно.

РЕДАКТИРОВАТЬ 2: Определения CFC следуют:

Contact.cfc

/**
 * @persistent true
 */
component name='Contact' {

    /**
     * @type numeric
     * @sqltype int(11)
     * @generator increment
     * @fieldtype id
     */
    property contactID;

    /**
     * @type string
     * @sqltype varchar(50)
     */
    property email;

    /**
     * @type array
     * @fieldtype one-to-many
     * @cfc Data
     * @fkcolumn dataID
     */
    property data;
}

Definition.cfc

/**
 * @persistent true
 */
component name='Definition' {

    /**
     * @type numeric
     * @sqltype int(11)
     * @generator increment
     * @fieldtype id
     */
    property definitionID;

    /**
     * @type string
     * @sqltype varchar(50)
     */
    property name;

    /**
     * @type array
     * @fieldtype one-to-many
     * @cfc Data
     * @fkcolumn dataID
     */
    property data;

}

Data.cfc

    /**
 * @persistent true
 */
component {

    /**
     * @type numeric
     * @sqltype int(11)
     * @generator increment
     * @fieldtype id
     */
    property dataID;

    /**
     * @type string
     * @sqltype varchar(50)
     */
    property value;

    /**
     * @fieldtype many-to-one
     * @fkcolumn contactID
     * @cfc Contact
     * @inverse true
     */
    property contact;

    /**
     * @fieldtype many-to-one
     * @fkcolumn definitionID
     * @cfc Definition
     * @inverse true
     */
    property definition;

}

1 Ответ

1 голос
/ 04 февраля 2012

Я полагаю, что вы хотите, чтобы отношения обрабатывались Data.cfc, имеющим

Data --m2o--> Contact
Data --m2o--> Definition

и для удобства

Contact --o2m--> Data (inverse=true)

CFC

// Contact.cfc
component persistent="true" {
  property name="contactID" fieldtype="id" generator="native";
  property name="email";
  property name="data" cfc="Data" fieldtype="one-to-many" inverse="true" lazy="true";
}

// Definition.cfc
component persistent="true" {
  property name="definitionID" fieldtype="id" generator="native";
  property name="name";
}

// Data.cfc
component persistent='true'{
  property name="dataID" fieldtype="id" generator="native";
  property name="value";
  property name="contact" cfc="Contact" fieldtype="many-to-one" fkcolumn="contactID";
  property name="definition" cfc="Definition" fieldtype="many-to-one" fkcolumn="definitionID";
}

index.cfm

<cfscript>
ormReload();
transaction {
    con = new Contact();
    con.setEmail("chris@domain.com");
    entitySave(con);

    def1 = new Definition();
    def1.setName("twitter");
    entitySave(def1);

    def2 = new Definition();
    def2.setName("interests");
    entitySave(def2);

    data1 = new Data();
    data1.setValue("d1rtym0nk3y");
    data1.setDefinition(def1);
    data1.setContact(con);
    entitySave(data1);

    data2 = new Data();
    data2.setValue("ColdFusion");
    data2.setDefinition(def2);
    data2.setContact(con);
    entitySave(data2);

    // this is important, you must set both sides of the relationship or "bad things" happen
    // i'd recommend overriding contact.addData()/data.setContact to ensure both sides get set
    con.addData(data1);
    con.addData(data2);
}
writeDump(con);
</cfscript>

Для разумного извлечения атрибутов данных для контакта вы можете сделать

myData = ormExecuteQuery("
    select new map(
        data.value as value,
        def.name as name
    )
    from Data data
    join data.definition def
    where data.contact.contactID = :id

", {id=con.getContactID()});

writeDump(myData);
...