지난 번 글에서 RESTful 프로그래밍을 할 때 구현해야 할 CRUD 연산 중 CREATE를 구현하기 위해 Rails 서버측 코드를 어떻게 고쳐야 하고, jQuery 코드를 어떻게 고쳐야 하는지를 살펴봤습니다. 그럼 오늘은 RETRIEVE, UPDATE, DELETE 연산을 어떻게구현하는지 살펴보도록 하죠.
RETRIEVE 연산은 두 가지가 있습니다. ID를 주고 그 ID에 해당하는 리소스를 조회하는 연산, 그리고 모든 리소스를 전부 조회하는 연산이 바로 그것이죠. 지난 시간에 보았던 location이라는 리소스의 경우를 생각해 본다면, 모든 location을 전부 조회하는 연산이 있을 수 있고, 특정한 location만을 조회하는 연산이 있을 수 있습니다. 그런데 가만히 생각해 보면 모든 location을 전부 조회하는 것은 그다지 바람직하지 않습니다. 뭔가 조건을 줄 수 있도록 하는 것이 좋죠.
그러니, rails의 scaffold 명령이 생성한 코드들 조금 고쳐 주어야 합니다. 아래의 코드를 보시죠.
# GET /locations
# GET /locations.xml
def index
if ( params[:elementid] )
@locations = Location.find(:all, :conditions =>
[ "elementid= ?", params[:elementid] ]);
else
@locations = Location.find(:all)
end
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => @locations }
format.js { render :json => @locations }
end
end
'모든 location을 조회하는 연산'은 LocationsController의 index 메소드에 의해 처리됩니다. 이 메소드에 전달되는 params 해쉬에 :elementid를 키로 하는 값이 있는 경우, 그 값을 조건으로 하여 location 리소스들을 검색하도록 코드를 변경했습니다.물론 그런 값이 없는 경우에는 하던 대로 하면 되구요.
클라이언트 코드는 다음과 같이 작성하면 됩니다. HTTP 메소드로 GET을 사용할 것이기 때문에 $.getJSON을 사용해 구현할 수 있습니다.
var loadLocations = function(options, callback) {
$.getJSON('locations', {elementid: options.elementid}, function(data) {
$.each( data, function(index, d) {
callback( d );
});
});
}
가져온 location 리소스 (json 형식입니다) 하나 하나를 callback 함수의 인자로 넘겨 처리하도록 하고 있습니다. 이 때 전달받은 데이터의 각 필드들을 접근하기 위해서는 d.location.id 뭐 이런 식으로 해야겠죠. 그런 부분은 일단 코드에서 다 뺐습니다. 구현하시는 분들이 알아서 하셔야 하는 부분이라서요.
어쨌든, RETRIEVE쪽은 이렇게 구현할 수 있습니다. RETRIEVE 연산 중 나머지 하나 (특정한 ID에 해당하는 리소스만들 조회하는 부분)는 다루지 않겠습니다. 여기까지만 아셔도 충분히 하실수 있으리라 믿고...
그럼 이제 CRUD 중 U, 즉 UPDATE를 하는 쪽을 알아보도록 하죠.
RETRIEVE를 통해 각각의 location 리소스에 할당된 id를 다 알아낼 수 있다는 것에 우선 유념하도록 합시다. 일단 rails 컨트롤러쪽 코드를 보면 다음과 같습니다.
# PUT /locations/1
# PUT /locations/1.xml
def update
@location = Location.find(params[:id])
respond_to do |format|
if @location.update_attributes(params[:location])
flash[:notice] = 'Location was successfully updated.'
format.html { redirect_to(@location) }
format.xml { head :ok }
format.json { render :json => {}, :status => :accepted }
else
format.html { render :action => "edit" }
format.xml { render :xml => @location.errors, :status => :unprocessable_entity }
format.json { render :xml => @location.errors, :status => :unprocessable_entity }
end
end
end
클라이언트가 참조한 URL에 붙어있는 ID값을 사용해 갱신할 location 객체를 찾은 다음, 갱신합니다. format.json이 어떻게 구현되어 있는지를 잘 보시기 바랍니다. 클라이언트가 json 데이터를 요구한 경우, format.json 안에서 head :ok만 해버리면 설사 rails 서버 쪽에서는 데이터베이스 갱신을 제대로 했다고 하더라도 웹 브라우저는 (그러니까 클라이언트) 이를 오류로 간주한다는 문제가 있습니다.
이 문제를 피해가기 위해서는 서버 쪽에서 비어있는 json 객체라도 만들어 클라이언트 쪽으로 던져줘야 합니다. :statis의 값은 저처럼 :accepted로 해도 되고, :ok로 해도 되겠죠.
여기에 대한 클라이언트 측 코드는 다음과 같습니다.
var updateLocation = function( options ) {
$.ajax( {
url: 'locations/' + options.id,
type: 'put',
data: {
'location[x]': options.pageX,
'location[y]': options.pageY,
'location[width]': options.width,
'location[width]': options.width
},
dataType: 'json'
}
);
}
type:의 값이 put이 되었다는 것 뺴고는 별거 없는 코드니까 설명은 생략하겠습니다. URL에 id를 붙여 주어야 한다는 점만 주의하면 되겠습니다. 그래야 어떤 아이템을 update할 것인지 서버가 알수 있을테니까요.
그럼 이제 CRUD 중 마지막 연산, DELETE를 한번 살펴보죠. 역시 rails 서버측 코드를 먼저 보겠습니다.
# DELETE /locations/1
# DELETE /locations/1.xml
def destroy
@location = Location.find(params[:id])
@location.destroy
respond_to do |format|
format.html { redirect_to(locations_url) }
format.xml { head :ok }
format.json { render :json => {}, :status => :accepted }
end
end
코드는 UPDATE의 경우와 비슷하므로, 설명은 생략하고 바로 클라이언트 코드로 넘어가겠습니다.
var deleteLocation = function( option ) {
$.ajax( {
url: 'locations/' + option.id,
type: 'delete',
dataType: 'json'
}
);
};
역시 URL에 삭제될 리소스의 ID가 붙어 들어간다는 것과, type이 delete로 지정되었다는 것을 제외하면 크게 새로울 것은 없는 코드입니다.
'Languages > Ruby or Rails' 카테고리의 다른 글
| jQuery를 사용한 Rails REST 프로그래밍 (2) (0) | 2008/10/15 |
|---|---|
| jQuery를 사용한 Rails REST 프로그래밍 (1) (0) | 2008/10/13 |
| Ruby의 inject를 활용한 코드 사례 (0) | 2008/10/10 |
| Rails에서 일반 .html 파일의 form과 연동시 발생할 수 있는 오류 (2) | 2008/08/01 |
| Rails로 Openid 로그인 기능 구현시 발생가능한 문제 (0) | 2008/07/29 |
| Ubuntu 8.04에서 passenger 설치 및 오류 대처법 (0) | 2008/07/17 |
댓글을 달아 주세요