관리 메뉴

새로운 시작, GuyV's lIfe sTyle.

레일즈로 파일업로딩 본문

ⓟrogramming

레일즈로 파일업로딩

가이브 2008.11.24 15:51



원본은  http://www.tutorialspoint.com/ruby-on-rails/rails-file-uploading.htm 이고,
대충 번역했다.




Rails를 이용한 파일업로딩


레일즈 명령어를 이용해 어플리케이션 본체 생성

C:\ruby> rails upload

업로드될 파일의 위치 결정. 이 자료들은 공용 구역에 저장됨
디렉터리를 만들고 퍼미션 체크


C:\ruby> cd upload
C:\ruby> mkdir upload\public\data
 

다음은 컨트로러와 모델 생성

모델 생성:
DB기반 어플리케이션이 아니기 때문에 아무 이름가능. DataFile 모델로 만듬.
(주:테이블에 대한 1또는 n에 대한 단/복수형 모델명을 지정을 해야되기 때문에..?)


C:\ruby> ruby script/generate model DataFile
      exists  app/models/
      exists  test/unit/
      exists  test/fixtures/
      create  app/models/data_file.rb
      create  test/unit/data_file_test.rb
      create  test/fixtures/data_files.yml
      create  db/migrate
      create  db/migrate/001_create_data_files.rb


data_file.rb 모델 파일에서 불러질 메소드(액션메소드?)를 생성한다.
이 메소드는 어플리케이션 컨트롤러에서 사용될 것이다.


class DataFile < ActiveRecord::Base
  def self.save(upload)
    name =  upload['datafile'].original_filename
    directory = "public/data"
    # create the file path
    path = File.join(directory, name)
    # write the file
    File.open(path, "wb") { |f| f.write(upload['datafile'].read) }
  end
end


위 함수는 CGI 객체 [업로드]를 받고 업로드된 파일명을 [original_filename] 함수를
이용해서 추출해(extract)주고, "public/data" 디렉터리에 저장될 것이다.
또한 [content_type] 함수를 이용해서 미디어 형식(mime?)을 불러올 수 있다.
 

여기서 [File]은 루비 객체이고 디렉터리명과 파일명을 합쳐서
전체파일경로(full file path) 를 리턴한다.


그 다음, File 객체에서 제공해주는 함수로 쓰기모드(write mode)로 연다.
또한 읽어진 파일을 출력파일로 쓸 수 있다.


컨트롤러 생성:
업로드용 컨트롤러 생성


C:\ruby> ruby script/generate controller Upload
      exists  app/controllers/
      exists  app/helpers/
      create  app/views/upload
      exists  test/functional/
      create  app/controllers/upload_controller.rb
      create  test/functional/upload_controller_test.rb
      create  app/helpers/upload_helper.rb
 

Now we will create two controller functions first function index will call a view file to take user input and second function uploadFile takes file information from the user and passes it to the 'DataFile' model. We set the upload directory to the 'uploads' directory we created earlier "directory = 'data'".

2개의 컨트롤러 함수를 만들건데, 하나는 뷰 파일에서 입력을 받을 [index] 이고,
다른 함수는 [uploadFile]로, 사용자가 DataFile 모델을 통해 올려진 파일의 정보를
얻는 것이다. 앞에서, uploads 디렉터리에 저장하기위해 "directory = data" 로 했다.
 

class UploadController < ApplicationController
  def index
     render :file => 'app\views\upload\uploadfile.rhtml'
  end
  def uploadFile
    post = DataFile.save(params[:upload])
    render :text => "File has been uploaded successfully"
  end
end
 

불러올 함수를 모델파일에 정의한다. [render] 함수는 view 파일로 메시지를
되돌려서 보여준다.


뷰 생성:
마지막으로 컨트롤러에서 언급한 [uploadfile.rhtml] 뷰 파일을 만든다.
대충 다음처럼..


<h1>File Upload</h1>
<%= start_form_tag ({:action => 'uploadFile'},
                        :multipart => true) %>
<p><label for="upload_file">Select File</label> :
<%= file_field 'upload', 'datafile' %></p>
<%= submit_tag "Upload" %>
<%= end_form_tag %>
 

여기까지가 설명한 모든 것들이다.
새로운 태그는 [file_field] 뿐이고, 이는 사용자의 컴퓨터에서 파일을 찾을 수 있는
버튼을 만들어준다.


multipart 파라미터를 참(true)로 설정하면, 파일을 binary file 형식으로 바로
인식한다.

여기서 중요한 것은 :action 에 메소드이름을 [uploadFile] 으로 업로드 버튼을 누르면
호출하기 위해서 지정한 것이다.

이는 다음화면처럼 보여준다.

[http://www.tutorialspoint.com/images/upload-file.gif]


업로드하면 app/public/data 디렉터리에 실제 파일명으로 저장되고 메시지가 보여진다.

NOTE: 디렉터리에 같은 파일명이 이미 존재하면 덮어쓸 것이다.

------------------------------------
대충 번역은 여기까지..
------------------------------------


Files uploaded from Internet Explorer:
Internet Explorer includes the entire path of a file in the filename sent, so the original_filename routine will return something like:


Files uploaded from Internet Explorer:
Internet Explorer includes the entire path of a file in the filename sent, so the original_filename routine will return something like:

C:\Documents and Files\user_name\Pictures\My File.jpg
 

instead of just:

My File.jpg
 

This is easily handled by File.basename, which strips out everything before the filename.

def sanitize_filename(file_name)
  # get only the filename, not the whole path (from IE)
  just_filename = File.basename(file_name)
  # replace all none alphanumeric, underscore or perioids
  # with underscore
  just_filename.sub(/[^\w\.\-]/,'_')
end
 

Deleting an existing File:
If you want to delete any existing file then its simple and need to write following code:

  def cleanup
    File.delete("#{RAILS_ROOT}/dirname/#{@filename}")
            if File.exist?("#{RAILS_ROOT}/dirname/#{@filename}")
  end
 

For a complete detail on File object, you need to go through Ruby Reference Manual.

 

 

 

 


 

'ⓟrogramming' 카테고리의 다른 글

티맥스 윈도우  (0) 2009.07.07
무료 SMTP 서버 (Vista 가능)  (1) 2009.02.11
레일즈로 파일업로딩  (0) 2008.11.24
MySQL CSV 파일 import  (0) 2008.11.20
APM6 + XP Mysql 한글깨짐 해결  (0) 2008.11.20
아파치 가상호스트 설정 예제.  (0) 2008.11.03
0 Comments
댓글쓰기 폼