The ideo of cross-reference tables is introduced in Propel 1.5. This means that an entity can get a list of related items as if it were a one-to-many relation. So in a person-to-groups relationship, a person can call getGroups()
, and a group can call getPersons()
.
This makes things much easier to handle. However, if an entity has a many-to-many relationship to itself, the names of the function calls become more complex. As an example, the following permits groups to contain groups within themselves:
group:
id: ~
name: { type: varchar(255) }
sub_group:
group_id:
type: integer
primaryKey: true
foreignTable: group
foreignReference: id
required: true
sub_group_id:
type: integer
primaryKey: true
foreignTable: group
foreignReference: id
required: true
For this relationship, Propel generates the awkwardly named functions getGroupsRelatedByGroupId()
and getGr开发者_如何学JAVAoupsRelatedBySubGroupId()
. These are long and not immediately obvious. As a user of this entity, I would much prefer to use the functions getParentGroups()
and getSubGroups()
, which I can understand more clearly. Is it possible to tell Propel to rename these functions? The phpName
attribute doesn't seem to do this.
The problem also occurs with one-to-many relations, as in the very simplified example below:
child:
id: ~
father_id:
type: integer
foreignTable: person
mother_id:
type: integer
foreignTable: person
Above, a Child object will be given the functions getPersonRelatedByFatherId()
and getPersonRelatedByMotherId()
, when it should be immediately obvious that getMother()
and getFather()
would work better. It's possible to write custom functions that do this, but it would make much more sense to be able to define it in the schema.
The solution is right here in the Propel docs but I've never noticed it until today: http://www.propelorm.org/documentation/04-relationships.html
Propel generates the setAuthor() method based on the phpName attribute of the element in the schema. When the attribute is not set, Propel uses the phpName of the related table instead.
Using your second example (in XML, but the conversion to YML should be simple):
<table name="person">
<column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true" />
<column name="father_id" type="integer" />
<column name="mother_id" type="integer" />
<foreign-key foreigntable="person" onDelete="setnull" phpName="father">
<reference local="father_id" foreign="id" />
</foreign-key>
<foreign-key foreigntable="person" onDelete="setnull" phpName="mother">
<reference local="mother_id" foreign="id" />
</foreign-key>
</table>
Notice the "phpName" attribute in the "foreign-key" element, that is where you set your custom relationship name. If you leave it blank (as I always did before today) it will use the "phpName" of the foreign relation table, or the table name itself if the phpName is not set on the table.
AFAIK it's not possible but Propel 1.6.3 generates better methods and fully integrates N-N relations and a fluent API is provided (setter/getter for collections for instance).
William
精彩评论