-1

我正在处理一个涉及 3 个不同对象的用户注册表单,即用户、会员资料和会员组织。我试图将所有这些嵌入到一个单一的注册表单中,例如用户 > 会员 > 学校。这个的基本实现在典型的sfDoctrineForm::embedRealtion过程中工作得很好。

问题是组织有一个唯一的索引member_number,唯一一次提供的值不会在数据库中是当该用户是第一个从他们的组织注册的人时。因此,在这种情况下,我们将收到一个验证错误(如果我们关闭验证,则会出现键约束违规)。

相反,我想要发生的是,我检查数据库中是否存在相同的 MemberOrganization member_number(在前/后验证器中或在 updateObject 或任何适当的地方)。如果成员编号已经存在,那么我想将新的 MemberProfile 与这个现有组织相关联,而不是将其链接到已提交的新成员,从​​而丢弃该组织的所有新值。

我尝试通过验证修改组织表单中的对象,但这总是会导致organization_id来自配置文件的约束违规:

$object = $this->getObject();
$table = $object->getTable();
$existing = $table->findOneByMemberNumber($values['member_number']);
if($existing)
{
  $members = clone $object->Members;
  $object->assignIdentifier($existing->identifier());
  $object->fromArray($existing->toArray(false), false);

  foreach($members as $member)
  {
    $member->link($object);
  }

  $values = $object->toArray(false); // return only the direct values
}

return $values;

架构看起来像这样:

User:
  columns:
  username: {type: string(100)}
  email: {type: string(255), unique: true}

MemberProfile:
  columns:
    # some none authentication related user details
    organization_id: {type: integer, notull: true}
    user_id: {type: integer, notnull: true}
  relations:
    User:
      local: user_id
      type: one
      foreign: id
      foreignType: one
    MemberOrganization:
      local: orgainization_id
      type: one
      foreign: id
      foreignType: many
      foreignAlias: Members

MemberOrganization:
  columns:
    membership_number: {type: string(255), unique: true}
    # other organization data
4

1 回答 1

0

所以我最终做的是覆盖bind顶层表单(用户表单)。在此方法中,我检查组织是否存在,如果存在,我将其附加到成员配置文件对象,然后重新嵌入所有子表单。

理想情况下,我实际上会在成员表单中执行此操作,但由于这些值仅绑定在顶级表单中,然后只是通过错误模式级联进行验证,这似乎是不行的。似乎需要完全重新嵌入才能使对象关联正确。

一些示例代码(在发出查询之前减少会员编号上的一些清理代码):

  public function linkOrganizationIfExists(array $orgValues)
  {
    $defaultOrg = $this->embeddedForms['member_profile']->embeddedForms['organization']->getObject();
    $table = $defaultOrg->getTable();

    if(isset($orgValues['member_number']) 
      && ($existingOrg = $table->findOneByMemberNumber($orgValues['member_number'])))
    {
      $user = $this->getObject();
      $profile = $user->getMemberProfile();
      $profile->Organization = $existingOrg;

      // prepare the current values from the db to return
      $orgValues = array_merge($orgValues, array_intersect_key($existingOrg->toArray(false), $orgValues));

      $this->embedRelation('MemberProfile as member_profile', 'MemberProfileRegisttrationForm');
    }

    return $orgValues;
  }

  public function bind(array $taintedValues = null, array $taintedFiles = null)
  {
    if(isset($taintedValues['member_profile']['organization']))
    {
      $taintedValues['member_profile']['organization'] = $this->linkOrganizationIfExists($taintedValues['member_profile']['organization']);
    }

    parent::bind($taintedValues, $taintedFiles);
  } 
于 2011-03-12T05:32:13.207 回答