Alloy Model에서 save시 id 관련 문의

안녕하세요. 김재경 입니다.

Alloy에서 전역 모델을 생성하여 저장하였는데 이해할 수 없는 경우가 있어서 질문드립니다.

우선 소스부터 설명드리면
User.js 라는 파일의 모델이 있구요.

 exports.definition = {  
   config: {
	
    "URL":  Alloy.CFG.rest_url + "/api/User/",
    "debug": 1, 
    "adapter": {
        "type": "restapi"
        /*"collection_name": "User",
        "idAttribute": "USER_ID" id missing error 방지  */  
    },
    "columns": {
    	"USER_ID" : "string",
    	"USER_NAME" : "string",
    	"EMAIL" : "string",
    	"USER_FG" : "string"
    	
    }
    
}, 

이하생략 …

이 모델을 alloy.js 에서 전역 선언하였습니다.

var UserModel = Alloy.Models.instance('User');

그리고 회원가입 화면에서 아래와 같이 저장합니다.

var model = Alloy.createModel("User"); 
	
			
	var params = {
		id : null,
		USER_ID : '', // 빈값으로 보내야 등록된다. 
	    USER_NAME : name,
	    EMAIL : email,
	    PASS : pass
	};

그리고 아래 코드는 가입시킨후 acs에서 동일한 아이디를 생성하고 acs키를 받아와 mssql에 업데이트 시켜주는 코드 입니다.

UserModel.save({id : null, 'USER_ID' : email, 'CLOUD_ID' : user.id }); 

코드를 잘 보시면 id를 null 값으로 보내고 있습니다.
이걸 하지 않으면 rest url 에 자동 생성된 guid가 달라붙어 날아가더라구요.
(restapi.js 소스에서 그렇게 보내는것 같습니다.)

restapi 서버쪽 코딩은 asp.net mvc 로 구현되어 있습니다.
사용자 테이블같은 경우 USER_ID 가 기본키인데 그걸 idAttribute 속성에 적용시키면 MISSING ID 에러가 납니다.

기본키를 다른걸로 지정하면 에러가나고 속성을 지우니 id = null 을 일일이 줘야하고 난감하네요.
Backbone을 잘 이해하지 못하다 보니 이런 패턴으로 구현하는건지도 의심스럽네요 ㅎㅎ

조언을 부탁드리겠습니다.

모델을 만들때 idAttribute로 사용할 필드명을 지정하지 않으면 자체적으로 id 값을 생성하게 됩니다. 이건 백본의 기본기능이구요. 모델.save()를 할때 id를 지정하지 않으면 서버에 모델을 새로 추가하겠다는 의미로 POST로 날라갑니다.
따라서 위처럼 id:null을 주거나 id를 지정하지 않으면 무조건 새로 생성하겠다는 의미입니다.

다만 모델을 만들때 idAttribute를 지정했다면 save를 호출시, 저장하려는 모델안에 idAttribute와 맵핑된 속성이 있다면 PUT(수정)으로 날리고, 없다면 POST(생성)로 날려줍니다.

네 처음에 id에 해당하는 필드명을 지정해 줬었어요.
그런데 아래처럼 에러가 나서 id = null 로 처리해 준 겁니다.

[REST API] ERROR: MISSING MODEL ID

처음에는 아래처럼 PRIMARY KEY인 USER_ID를 지정해줬었지요.
그런데 왜 MISSING ID가 나오는지 모르겠어요.

"adapter": {
            "type": "restapi",
            "idAttribute": "USER_ID"  
        },

소스코드를 좀 봐야할것 같은데,… “USER_ID” 라는 이름으로 ACS 데이터 베이스에 필드를 만드신건가요?
ACS랑 연동할때 특별한 이름으로 primary 키값을 지정하지 않았다면 보통은 "id"라는 이름으로 지정해 쓰는것이 일반적이에요. 왜냐면 모든 ACS 모델 객체가 디폴트로 id 값을 가지거든요.
따라서 “idAttribute”: “id” 라고 지정해보세요. 제 기억이 맞다면 "id"라고 지정해서 쓰면 문제 없을꺼에요.

앗 죄송해요. 제가 적어놓질 못했네요.
ACS가 아니고 아래 주소에 있는 restapi.js 어댑터를 사용한 거예요.

https://github.com/viezel/napp.alloy.adapter.restapi

restapi는 제가 별도로 만든 서버를 바라봅니다.
거기 호출할때 키가 user_id 필드이구요.

서버 url호출 되기전에 이미 missing id 에러가 생겨버리네요 ㅠㅠ
말씀처럼 user_id를 id로 변경하니 이것도 잘되긴 합니다.
그런데 서버쪽 키값이랑 이름이 달라지니 가독성의 문제가 생길것 같습니다.

다른 모델도 바꾼 필드명 대신 id로 바꾸니가 잘되네요.

restapi.js 에서 문제가 생긴 부분은 여기네요.
idAttribute에서 id말고 다른걸 적으면 에러가 납니다.

 case 'update' :
	if (!model[model.idAttribute]) {
	        params.error(null, "MISSING MODEL ID");
		Ti.API.error("[REST API] ERROR: MISSING MODEL ID");
		return;
     }

제가 일단 대략적으로 살펴보니 restapi 아답터에서
model[model.idAttribute]라고 쓰인 코드 전부를 mode.id라고 바꾸면 정상작동할 것으로 보입니다.^^ 이렇게 id에 접근하면 id가 안나오죠.

나중에 시간될때 다시 볼께요.

위에서 제가 말한 이유가 맞습니다. restapi 버그입니다.
수정해서 pull request 보냈어요. :slight_smile:

종은님 수정해서 해보니까 잘 됩니다 ^^
이것 때문에 여기저기 많이 훓어보게 되었네요 ㅎㅎ
Arrow에선 mssql 아답터가 별도로 나오는것 같던데 둘다 비교해 봐야겠네요.
감사합니다. 막히면 또 여쭤볼게요 ^^

1개의 좋아요