관계

관계는 Cloud SQL 모델에서 레코드 간의 잠재적인 연결을 나타내며, 하나의 레코드가 하나 이상의 다른 레코드와 연결될 수 있는 능력을 나타냅니다. 예를 들어 소셜 앱의 Person 모델에 두 사람 간의 우정을 나타내는 Friends 관계가 있을 수 있습니다.

관계 기본사항

App Maker에서 관계는 양방향입니다. 각 방향을 관계 종단이라고 하며, 관계 종단마다 두 가지 속성이 있습니다.

  • 이름 — 관계 종단의 이름이며 데이터 바인딩 및 스크립트에서 관계를 나타내는 데 사용됩니다.
  • 개수 — 관계 종단에서 지원하는 연결의 수입니다. 개수가 하나로 설정되면 레코드가 단 하나의 연결만 수락한다는 의미이고, 다수로 설정되면 레코드가 무제한적인 수의 연결을 수락한다는 의미입니다. 관계는 일대일, 일대다, 다대다일 수 있습니다. 개수-대-개수의 값을 카디널리티 또는 관계의 범위라고 합니다.

예를 들어 HR 앱에서 EmployeeDB 모델과 Teams 모델 사이의 관계를 사용하여 직원과 팀을 나타낼 수 있습니다. 각 직원이 여러 팀의 구성원일 수 있으므로 EmployeeDBTeams 간에 다대다 관계를 만듭니다. 관계 종단에는 다음과 같은 속성이 있습니다.

  • 이름=Members, 개수=다수
  • 이름=Teams, 개수=다수

또한 팀마다 한 명의 관리자가 존재하고 동일한 관리자가 여러 팀을 관리할 수 있으므로 EmployeeDBTeams 간에 일대다 관계를 만들 수 있습니다. 관계 종단에는 다음과 같은 속성이 있습니다.

  • 이름=Manager, 개수=하나
  • 이름=Teams, 개수=다수

관계 만들기 및 편집

관계를 만들려면 다음 안내를 따르세요.

  1. Cloud SQL 모델을 클릭하고 관계 탭으로 이동합니다.
  2. 관계를 만들려면 관계 추가를 클릭합니다. 만들기 마법사를 사용하여 다음을 수행합니다.

    1. 다른 관계 종단의 대상 모델을 설정합니다.
    2. 각 관계 종단에 대하여 개수를 선택합니다.
    3. (선택사항) 기본값을 유지하지 않으려면 각 관계 종단의 이름을 입력합니다.
    4. (선택사항) 일대일 및 일대다 관계의 경우 개수가 하나인 관계 종단의 소유자를 선택합니다. 다음과 같은 경우에만 관계에 소유자 모델을 지정하세요.
  3. 만들기를 클릭합니다.

관계를 만든 후에 관계 종단의 이름을 편집할 수 있습니다. 개수가 하나인 관계 종단의 경우 소유권을 사용 설정하거나 사용 중지할 수 있습니다. 개수가 여러 개인 관계 종단의 경우 정렬 방식을 변경할 수 있습니다.

관계를 편집하려면 다음 안내를 따르세요.

  1. 모델을 클릭하고 관계 탭으로 이동합니다.
  2. 관계 목록에서 관계 종단 이름을 클릭합니다.

    두 모델의 레코드를 연결하는 관계의 경우, 각 모델의 관계 목록에는 반대쪽 모델의 관계 종단 이름만 표시됩니다. 같은 모델의 레코드를 연결하는 관계의 경우, 두 관계 종단이 모두 나열됩니다. EmployeeDB 모델 예시에서는 ManagerMembers가 모두 관계 탭에 나열됩니다.

  3. 이름, 소유자 또는 정렬을 편집합니다. 변경사항은 자동으로 저장됩니다.

    정렬을 설정하려면 레코드 정렬에 사용할 필드를 선택하세요. 오름차순 체크박스를 선택하여 관계 종단의 레코드 정렬 순서를 설정합니다. 정렬 환경설정을 지정하지 않으면 모델의 데이터 백엔드가 정렬 순서를 결정합니다.

관련 레코드의 소유권

최소한 하나의 관계 종단에서 개수가 하나인 관계에는 일정한 규칙에 따라 소유자를 지정할 수 있습니다. 소유자를 설정할 때는 두 모델에서 연결된 레코드에 대하여 소유자가 소유한 관계를 만듭니다.

  • 소유권 있음 — 사용자 또는 앱 로직이 소유자 모델에서 레코드를 삭제하면 소유자가 있는 연결된 레코드를 앱이 모두 삭제합니다. 소유자가 있는 레코드가 삭제되어도 소유자 레코드는 삭제되지 않습니다.
  • 소유권 없음 — 관계의 종단 어느 한쪽에서 레코드가 삭제되어도 다른 종단에서 레코드가 삭제되지 않습니다.

다음 조건이 모두 참인 경우에만 관계에서 소유자 모델을 지정하세요.

  • 소유자가 있는 레코드는 소유자 레코드 없이 존재하지 않아야 합니다.
  • 소유자 레코드가 삭제되면 소유자가 있는 관계 종단의 레코드가 자동으로 삭제되게 하려고 합니다.

소유권 예시

송장이 삭제되는 경우 송장 항목이 삭제되도록 하면 좋습니다. InvoiceItem 모델 간에 일대다 관계가 있으면 Invoice 모델을 소유자로 만듭니다. 사용자가 Invoice 레코드를 삭제하면 소유자가 있는 모든 Item 레코드, 즉 삭제된 Invoice 레코드와 연결되어 있던 레코드를 앱이 삭제합니다.

삭제되는 레코드는 항목의 카테고리(예: 보관하는 디스크 드라이브의 종류)가 아니라 항목의 특정 인스턴스(예: 인벤토리의 특정 디스크 드라이브)입니다.

소유자 관계

  • 일대일 또는 일대다 관계의 한쪽에 있는 모델만 소유자일 수 있습니다.
  • 레코드 A가 레코드 B를 소유하고 레코드 B가 레코드 A를 소유하는 경우와 같이 소유권의 순환이 생성된다면 모델을 소유자로 지정할 수 없습니다.
  • 소유자가 소유한 관계를 연결할 수 있습니다. 예를 들어 다음과 같은 모델 및 관계가 있는 경우를 가정합니다.

    • Forum, Topic, Comment 모델
    • Forum에서 Topic으로의 일대다 관계(Forum 모델이 소유자)
    • Topic에서 Comment로의 일대다 관계(Topic 모델이 소유자)

    Topic 레코드를 삭제하면 연결된 모든 Comment 레코드를 App Maker가 삭제합니다. Forum 레코드를 삭제하면 연결된 모든 Topic 레코드와 이러한 레코드에 연결된 Comment 레코드도 App Maker에서 삭제합니다.

  • 여러 관계가 포함된 하나의 모델을 여러 소유자 모델이 소유할 수 있습니다.

  • 소유자 모델에서 레코드를 삭제하면 해당 레코드에 연결된 소유자 있는 레코드가 다른 모델에 있는 레코드의 소유여도 App Maker에서 이를 삭제합니다.

레코드 간의 연결 관리

연결은 모델 관계를 통한 두 레코드 간의 실제 링크입니다. 예를 들어 ManagerTeams라는 관계 종단 사이에 일대다 관계가 있으면 Manager1의 레코드와 각 팀의 레코드 간에 연결이 존재합니다.

앱의 워크플로에 따라 세 가지 방법으로 레코드 간의 연결을 만들고 수정할 수 있습니다.

  1. 위젯이 레코드의 연결을 표시하거나 변경할 수 있게 하려면 데이터 바인딩을 사용합니다.
  2. 데이터 바인딩으로 불가능한 복잡한 연결 변경을 처리하려면 클라이언트 스크립트를 사용합니다.
  3. 일괄 변경을 처리하거나 변경을 안전하게 수행하려면 서버 스크립트를 사용합니다.

데이터 바인딩을 사용하여 연결 수정

데이터 바인딩을 통해 레코드 간의 연결을 변경하는 많은 방법이 있지만 가장 간단한 방법은 관계 종단을 모델 데이터 소스의 item 속성으로서 액세스하는 것입니다. 모델 데이터 소스에서 관계 종단은 필드와 마찬가지로 레코드 속성으로 노출됩니다.

위젯 표시를 사용 설정하거나 현재 선택된 레코드의 연결된 레코드를 변경하려면 위젯의 value@datasource.item.[relation end name]으로 바인딩하세요. 이 방법은 특히 드롭다운 위젯(관계 종단에 개수가 1개인 경우)과 다중 선택 상자(관계 종단에 개수가 다수인 경우)에 유용합니다. 예를 들면 데이터 모델 연결 가이드를 사용해 보세요. 직원을 나열하는 UI 요소를 만들 때 위젯 값과 데이터 소스 사이에 바인딩을 설정합니다.

클라이언트 스크립트로 연결 수정

이 방법은 데이터 소스가 이미 레코드의 연결된 레코드를 로드했는지 확인해야 하므로 데이터 바인딩보다 어렵습니다. 연결된 레코드가 로드되었는지 확인하는 방법은 다음과 같습니다.

  • 데이터 소스의 프리페치를 사용 설정합니다.
  • 레코드에서 _loadRelation-name을 호출하고 비동기 콜백을 기다립니다.
  • 관계 데이터 소스의 onLoad 이벤트를 기다립니다.
  • 관계 데이터 소스를 사용하는 위젯의 onDataLoad 이벤트를 기다립니다.

예를 들어 이전의 EmployeeDB-Team 관계 시나리오를 기반으로 빌드하려면 다음 코드를 사용하여 레코드를 연결합니다(관리자를 팀 구성원에 지정하고 팀 구성원을 관리자의 팀에 추가). 올바른 직원 레코드에 더 쉽게 액세스할 수 있도록 하기 위해 EmployeeDB 모델에 2개의 데이터 소스를 만들었습니다.

  1. Manager - 관리자를 선택할 수 있는 데이터 소스
  2. Member - 팀 구성원을 선택할 수 있는 데이터 소스
    var managerRecord = app.datasources.Manager.item;
        var teamRecord = app.datasources.Teams.item;

        // Assign the manager to the team.
        teamRecord.Manager = managerRecord;

        // Changes are saved automatically if the datasource in auto-save mode

        // Add a team member to a Manager's team.
        // Note: Retrieve Members on the client before proceeding, such as by using prefetch option in datasource - datasources Team -> Members)
        var engineerRecord = app.datasources.TeamMember.item;
        teamRecord.Members.push(engineerRecord);
    

서버 스크립트로 연결 수정

연결된 레코드가 로드될 때 염려할 필요가 없으므로 서버 스크립트에서 연결을 수정하는 방법이 더 쉽습니다. 적절한 레코드에 액세스한 다음 관계 종단 속성을 사용하여 관계를 통해 레코드를 연결하세요.

예를 들어 이전의 EmployeeDB-Team 관계 시나리오를 기반으로 빌드하려면 다음과 같은 서버 스크립트를 사용하여 팀에 관리자와 구성원을 추가합니다.

// Get the record for the Team to modify.
    var teamRecord = app.models.Teams.getRecord("team1");

    // Assign a manager to the Team.
    var managerRecord = app.models.EmployeeDB.getRecord("manager1");
    teamRecord.Manager = managerRecord;

    // Note: The new association is not saved yet

    // Assign a team member to the Team.
    var engineerRecord = app.models.EmployeeDB.getRecord("engineer1");
    teamRecord.Members.push(engineerRecord);

    // Save both changes to the database.
    app.saveRecords([teamRecord]);
    

관계 필터링

관련 Cloud SQL 모델의 필드를 기준으로 레코드를 필터링하거나 정렬하려면 뒤에 필드 이름이 붙는 관계 이름을 추가합니다. 예를 들어 Mother 관계를 관련 레코드의 Age 필드로 필터링하려면 Mother.Age를 사용하세요.

또한 연결된 레코드 또는 레코드 키에 equals, notEquals, in, notIn 필터를 적용할 수도 있습니다. 예를 들어 관리자의 관리자가 올바르게 지정되었는지 확인하려면 Manager.Manager._key._equals로 필터링합니다.

관계 필터링은 데이터 바인딩서버 스크립팅에서 사용할 수 있습니다.

추가 자료