Ruby on Rails 2.1 - Tải lên tệp
Bạn có thể có một yêu cầu trong đó bạn muốn khách truy cập trang web của mình tải lên một tệp trên máy chủ của bạn. Rails làm cho nó rất dễ dàng để xử lý yêu cầu này. Bây giờ, chúng ta sẽ tiến hành một dự án Rails đơn giản và nhỏ.
Như thường lệ, hãy bắt đầu với một ứng dụng Rails mới có tên upload. Hãy tạo một cấu trúc cơ bản của ứng dụng bằng cách sử dụng lệnh rails đơn giản.
C:\ruby> rails -d mysql upload
Hãy quyết định nơi bạn muốn lưu các tệp đã tải lên của mình. Giả sử đây làdatathư mục bên trong phần công khai của bạn. Vì vậy, hãy tạo thư mục này và kiểm tra các quyền.
C:\ruby> cd upload
C:\ruby\upload> mkdir upload\public\data
Bước tiếp theo của chúng ta sẽ như thường lệ, tạo bộ điều khiển và mô hình.
Tạo mô hình
Vì đây không phải là một ứng dụng dựa trên cơ sở dữ liệu, chúng tôi có thể giữ bất kỳ tên nào phù hợp với chúng tôi. Giả sử chúng ta phải tạo mộtDataFile mô hình.
C:\ruby\upload> 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
Bây giờ, chúng ta sẽ tạo một phương thức có tên là save trong data_file.rbtệp mô hình. Phương thức này sẽ được gọi bởi bộ điều khiển ứng dụng.
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
Hàm trên sẽ lấy đối tượng CGI upload và sẽ trích xuất tên tệp đã tải lên bằng chức năng trợ giúp original_filenamevà cuối cùng, nó sẽ lưu trữ tệp đã tải lên vào thư mục "public / data". Bạn có thể gọi hàm trợ giúpcontent_type để biết loại phương tiện của tệp đã tải lên.
Đây File là một vật thể ruby và join là một hàm trợ giúp sẽ nối tên thư mục với tên tệp và sẽ trả về đường dẫn đầy đủ của tệp.
Tiếp theo, để mở tệp ở chế độ ghi, chúng tôi đang sử dụng chức năng trợ giúp mở được cung cấp bởi Filevật. Hơn nữa, chúng tôi đang đọc dữ liệu từ tệp dữ liệu được truyền và ghi vào tệp đầu ra.
Tạo bộ điều khiển
Bây giờ, hãy tạo bộ điều khiển cho dự án tải lên của chúng tôi -
C:\ruby\upload> 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
Bây giờ, chúng ta sẽ tạo hai hàm điều khiển. Chức năng đầu tiênindex sẽ gọi một tệp dạng xem để nhận đầu vào của người dùng và hàm thứ hai uploadFilelấy thông tin tệp từ người dùng và chuyển nó đến mô hình 'DataFile'. Chúng tôi đặt thư mục tải lên thành thư mục 'tải lên' mà chúng tôi đã tạo trước đó "directory = 'data'".
class UploadController < ApplicationController
def index
render :file => 'app\views\upload\uploadfile.html.erb'
end
def uploadFile
post = DataFile.save( params[:upload])
render :text => "File has been uploaded successfully"
end
end
Ở đây, chúng tôi đang gọi hàm được xác định trong tệp mô hình. Cácrender đang được sử dụng để chuyển hướng đến xem tệp cũng như hiển thị thông báo.
Tạo chế độ xem
Cuối cùng, chúng tôi sẽ tạo một tệp xem uploadfile.rhtml,mà chúng tôi đã đề cập trong bộ điều khiển. Điền vào tệp này bằng mã sau:
<h1>File Upload</h1>
<% form_tag ({:action => 'uploadFile'},
:multipart => true) do %>
<p><label for="upload_file">Select File</label> :
<%= file_field 'upload', 'datafile' %></p>
<%= submit_tag "Upload" %>
<% end %>
Ở đây mọi thứ giống như những gì chúng tôi đã giải thích trong các chương trước. Thẻ mới duy nhất làfile_field, sẽ tạo một nút để chọn tệp từ máy tính của người dùng.
Bằng cách đặt tham số nhiều phần thành true, bạn đảm bảo rằng hành động của mình được truyền đúng cách dọc theo dữ liệu nhị phân từ tệp.
Ở đây, một điểm quan trọng cần lưu ý là chúng tôi đã chỉ định "uploadFile" như tên phương thức trong :action, sẽ được gọi khi bạn nhấp vào Upload cái nút.
Nó sẽ hiển thị cho bạn một màn hình như sau:
Bây giờ, bạn chọn một tập tin và tải nó lên. Tệp này sẽ được tải lên thư mục app / public / data với tên tệp thực và một thông báo sẽ hiển thị cho biết "Tệp đã được tải lên thành công".
NOTE - Nếu một tệp có cùng tên đã tồn tại trong thư mục đầu ra của bạn, thì tệp đó sẽ bị ghi đè.
Tệp được tải lên từ Internet Explorer
Internet Explorer bao gồm toàn bộ đường dẫn của tệp trong tên tệp được gửi, vì vậy original_filename thói quen sẽ trả về một cái gì đó như -
C:\Documents and Files\user_name\Pictures\My File.jpg
Thay vì chỉ -
My File.jpg
Điều này có thể dễ dàng xử lý bằng File.basename, loại bỏ mọi thứ trước tên tệp.
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
Xóa một tệp hiện có
Nếu bạn muốn xóa bất kỳ tệp nào hiện có, nó khá đơn giản. Tất cả những gì bạn cần làm là viết đoạn mã sau:
def cleanup
File.delete("#{RAILS_ROOT}/dirname/#{@filename}")
if File.exist?("#{RAILS_ROOT}/dirname/#{@filename}")
end
Để biết chi tiết đầy đủ về File đối tượng, bạn cần phải đi qua Ruby Reference Manual.