2013-10-31 37 views
1

我有一個多對多的關係設置,並且需要控制順序。CF ORM多對多關係排序順序

我有一個實體與下面的屬性。如何通過這種關係檢索組件的順序?

property name="Components" fieldtype="many-to-many" cfc="CmsComponent" 
     type="array" 
     singularname="Component" 
     linktable="CMSPageComponents" 
     fkcolumn="page_id" 
     inversejoincolumn="component_id"; 

我設置在linktable(CMSPageComponents)一列名爲dispOrder。但是當我在上面的屬性上設置orderby="dispOrder"orderby="CMSPageComponents.dispOrder"屬性時,它似乎忽略了它。

有關如何控制多對多關係的順序的任何建議?

+0

據我所知很多一對多其實並不是太應用廣泛而且相當有限。嘗試將其轉換爲一對多,排序順序應該得到很好的支持。 – Henry

+0

是的,一對多確實很容易排序,但我需要多對多。一對多隻是不能提供我需要的功能。 – Jason

+1

什麼功能?多對多基本上只是一對一對多的關係。如果你想在鏈接表上使用order by,那麼afaik將它提升爲一個實體就是你需要做的事情。 –

回答

3

當關系是多對多時,CF將把orderBy語句應用於對象表而不是鏈接表。因此,在理論上則可以將dispOrder列從CMSPageComponents移動鏈接表到CmsComponent表,使其工作。

但實際上,我期望排序是特定於多對多關係(即特定頁面),在這種情況下,您可以遵循彼得的建議並創建一個單獨的實體,鏈接其他兩個實體並讓您定義一個訂單屬性。

所以,你將有3個實體:

  1. CmsPage
  2. CmsComponent
  3. CmsPageComponent

CmsPageComponent可能是這個樣子:

<cfcomponent displayname="CmsPageComponent" persistent="true" table="cmsPageComponents"> 
    <!--- Add a primary key for the link Entity ---> 
    <cfproperty name="ID" fieldType="id" generator="native"> 
    <cfproperty name="dispOrder"> 
    <cfproperty name="page" fieldType="many-to-one" cfc="CmsPage" fkColumn="pageID"> 
    <cfproperty name="component" fieldType="many-to-one" cfc="CmsComponent" fkColumn="componentID"> 
    <!--- init() etc ---> 
</cfcomponent> 

CmsPage然後可以與使用dispOrder列中的鏈接實體允許訂購一個一對多的關係:

<cfcomponent displayname="CmsPage" persistent="true" table="cmsPages"> 
    <cfproperty name="ID" fieldType="id" generator="native"> 
    <cfproperty name="pageComponents" singularName="pageComponent" fieldType="one-to-many" cfc="PageComponent" fkColumn="pageID" orderBy="dispOrder"> 
    <!--- init() etc ---> 
</cfcomponent> 

更新 以下說明了如何添加和顯示頁面組件。不是唯一的或必然最好的辦法,但只給你一個想法:

<cfscript> 
transaction{ 
    //load the page 
    page = EntityLoadByPK("CmsPage",1); 
    //load the components we want to add 
    component1 = EntityLoadByPK("CmsComponent",1); 
    component2 = EntityLoadByPK("CmsComponent",2); 
    //create link objects 
    pageComponent1 = EntityNew("CmsPageComponent"); 
    pageComponent2 = EntityNew("CmsPageComponent"); 
    // link them to the pages and components in the order we want 
    pageComponent1.setComponent(component1); 
    pageComponent1.setPage(page); 
    pageComponent1.setDispOrder(2); 
    EntitySave(pageComponent1); 
    pageComponent2.setComponent(component2); 
    pageComponent2.setPage(page); 
    pageComponent2.setDispOrder(1); 
    EntitySave(pageComponent2); 
} 
//Reload from the database so the order is applied 
EntityReload(page); 
</cfscript> 
<!DOCTYPE html> 
<html> 
<head> 
    <title>Test</title> 
</head> 
<body> 
    <cfoutput> 
     <h2>Page #page.getID()#</h2> 
     <ol> 
      <cfloop array="#page.getPageComponents()#" index="pageComponent"> 
       <cfset component = pageComponent.getComponent()> 
       <li>Component ID #component.getID()#, Display Order = #pageComponent.getDispOrder()#)</li> 
      </cfloop> 
     </ol> 
    </cfoutput> 
</body> 
</html> 

注:這是假定的ORM設置flushAtRequestEnd是真正的Application.cfc

+0

感謝CFSimplicity!感謝你的解釋,我想我明白彼得現在在做什麼。但我仍然無法看到這可以模擬多對多。我無法想象如何將組件添加到頁面中,或者獲取組件列表而不會使它變成一個複雜的過程?我是否更好地恢復到標準的SQL查詢來使用當前的多對多設置來檢索組件?再比你一次! – Jason

+0

我在示例中添加了更多代碼,以顯示您可以使用中間對象關係添加和顯示組件。這確實是一個更復雜的問題,但確實給了你更多的靈活性,並且解決了CF訂購多對多的限制。 – CfSimplicity

+0

謝謝CfSimplicity!這很有用。我實際上認爲它會實施起來很麻煩,但最終,除了設置多對多之外,沒有什麼更多的了。謝謝! – Jason

相關問題