When the relationship is many-to-many CF will apply the orderBy
statement to the object table not to the link table. So in theory you could move your dispOrder column from the CMSPageComponents link table to the CmsComponent table to make it work.
But in practice I expect the ordering is specific to the many-to-many relationship (i.e. the particular page), in which case you could follow Peter's advice and create a separate entity which links the other two entities and lets you define an order property.
So you would have 3 entities:
- CmsPage
- CmsComponent
- CmsPageComponent
CmsPageComponent might look something like this:
<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 could then have a one-to-many relationship with the link entity allowing ordering using the dispOrder column:
<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>
Update The following shows how you might add and display page components. Not the only or necessarily best way, but just to give you an idea:
<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>
NOTE: this assumes the ORM setting flushAtRequestEnd
is true in Application.cfc