輕松掌握Ruby on Rails上傳圖片實現(xiàn)技巧
Ruby on Rails作為一種WEB開發(fā)框架,擁有許多關(guān)于網(wǎng)站建設(shè)的功能,幫助我們簡單完善自身的網(wǎng)站開發(fā)。比如圖片的上傳等。下面我們就為大家介紹Ruby on Rails上傳圖片的相關(guān)技巧。#t#
我們希望當(dāng)新增留言的時候,允許用戶上傳圖片,并能判斷上傳文件的類型是否為圖片和文件是否過大。這在Rails中不難做到,不需要使用任何插件,只用十分簡潔的代碼即可實現(xiàn)Ruby on Rails上傳圖片!這的確是一件讓程序員愉快的事情。
修改/app/views/message路徑下的new.rhtml視圖文件。修改后的代碼如下:
- < table valign="top" width="100%"
border="0" cellspacing="0" cellpadding="0"> - < tr>
- < td>
- < center>
- < %= error_messages_for 'message' %>
- < /center>
- < !-- 將multipart選項設(shè)置為true,允許上傳文件 -->
- < %= start_form_tag ({ :action =>
'create', :id => @message }, :multipart => true) %> - < table align="center" width="400"
border="0" cellpadding="0" cellspacing="0" - bgcolor="#BFCAE6">
- < tr>
- < td colspan="2" id="title">新增留言< /td>
- < /tr>
- < tr>
- < td width="15%">< b>標(biāo)題< /b>< /td>
- < td >< %= text_field('message',
'title', :size => "30")%>< /td> - < /tr>
- < tr>
- < td width="15%">< b>內(nèi)容< /b>< /td>
- < td >< %= text_area 'message',
'detail', "cols" => 40, "rows" => 10 %>< /td> - < /tr>
- < tr>
- < td width="15%">< b>貼圖< /b>< /td>
- < !-- 調(diào)用file_field幫助方法,生成一個文件域 -->
- < td >< %= file_field 'message', 'picture' %>< /td>
- < /tr>
- < tr>
- < td colspan="2" align="center"><
%= submit_tag '提交' %>< /td> - < /tr>
- < /table>
- < %= end_form_tag %>
- < /td>
- < /tr>
- < /table>
上面的Ruby on Rails上傳圖片代碼在start_form_tag幫助方法中指定multipart的選項值為true,使得該表單能夠發(fā)送文件數(shù)據(jù)。并且,通過調(diào)用file_field幫助方法,生成了一個文件域。這里的picture屬性只是個虛擬屬性,因為在數(shù)據(jù)庫的messages表中并不存在這個屬性。這需要我們對這個虛擬屬性做一些處理,使之對應(yīng)messages表中的真實屬性。具體實現(xiàn)方式下面會有詳細(xì)介紹。
上面的表單是沒有為留言時間設(shè)計表單域的,因為我們可以通過更簡便的方式來為Message對象的這個屬性賦值:messages表中表示留言時間的字段名為created_at,數(shù)據(jù)類型設(shè)計為timestamp,這樣,當(dāng)保存一條Message對象對應(yīng)的記錄時,Rails就會自動將當(dāng)前時間賦值給created_at列,而不需要我們手動賦值。
在message_controller.rb控制器文件中,需要修改create方法,修改后該方法的Ruby on Rails上傳圖片代碼片段如下。
- def create
- # 查找出當(dāng)前留言的User對象
- user=User.find(session[:user_id])
- # 將該User對象賦值給參數(shù)中
Message對象的user屬性- params[:message][:user]=user
- # 構(gòu)造一個Message對象,
并使用message參數(shù)來初始化該對象- @message = Message.new(params[:message])
- # 如果Message對象能成功保存進(jìn)數(shù)據(jù)庫
- if @message.save
- flash[:notice] = '新增留言成功!'
- # 重定向到list Action
- redirect_to :action => 'list'
- else
- # 提交new Action
- render :action => 'new'
- end
- end
在create方法的定義中,前面兩句代碼是scaffold生成的默認(rèn)代碼中所沒有的。這是因為user_id是messages表參照users表的外鍵列,scaffold不會自動生成對外鍵列的操作。所以,我們需要根據(jù)session[:user_id]來查找出留言的User對象,并把該對象賦值給表單參數(shù)中的Message對象,作為它的一個user屬性。這樣,當(dāng)Message對象調(diào)用save方法保存進(jìn)數(shù)據(jù)庫的時候,會讓該Messge對象對應(yīng)的數(shù)據(jù)行參照到該User實例對應(yīng)的數(shù)據(jù)行。
在Message Model文件中,重定義一個picture=方法。因為我們的new.rhtml視圖文件中有一個picture表單域,當(dāng)提交表單后控制器將發(fā)送一個message[:picture]的請求參數(shù),這個請求參數(shù)將要求Message類里包含一個picture=方法,該方法用于接受message[:picture]請求參數(shù)。
picture=方法負(fù)責(zé)把message[:picture]請求參數(shù)(這個請求參數(shù)值是一個文件對象,里面包含了非常豐富的信息)解析出來。下面是picture=方法的代碼:
- # 提供picture=方法,將一個picture
的表單域設(shè)置成Message對象的多個屬性- def picture=(picture_field)
- transaction do
- # 如果用戶上傳了圖片
- if picture_field.size>0 then
- # @picture_size為上傳圖片的文件大小
- @picture_size=picture_field.size
- # @picture_type為上傳圖片的文件類型
- @picture_type=picture_field.content_type.chomp
- # 設(shè)置Message對象的picture_content_type屬性
- self.picture_content_type =@picture_type
- # 設(shè)置Message對象的picture_data屬性
- self.picture_data = picture_field.read
- end
- end
- end
提供了picture=方法之后,我們就將message[:picture]請求參數(shù)與messages表中的真實屬性picture_content_type和picture_data對應(yīng)起來了。
在Ruby on Rails上傳圖片方面,Rails處理得很好,表單中的文件域參數(shù)值不再是一個簡單的類型值,而是已經(jīng)被包裝成一個文件對象,它也有size,content_type和read方法,直接調(diào)用這些方法,即可返回這個文件對象的大小、文件類型和包含的二進(jìn)制數(shù)據(jù)。
當(dāng)用戶添加一條留言時,我們需要對留言對象進(jìn)行模型校驗,這可以通過在message.rb模型文件中重寫validate方法來實現(xiàn)。代碼如下:
- def validate
- # 驗證title不能為空
- errors.add("", "標(biāo)題不能為空") if title.empty?
- # 驗證detail不能為空
- errors.add("", "內(nèi)容不能為空") if detail.empty?
- # 下面校驗上傳的圖片
- if @picture_type != nil
- # 校驗上傳圖片的文件類型
- errors.add("", "貼圖不是合法的圖片文件")
unless @picture_type =~ /^image/- end
- if @picture_size != nil
- # 校驗上傳圖片的文件大小
- errors.add("", "貼圖文件太大,應(yīng)不能超過50
KB") if @picture_size > MAX_IMAGE_SIZE- end
- end
在上面的Ruby on Rails上傳圖片代碼中,我們校驗留言標(biāo)題、留言內(nèi)容的值不能為空,上傳的文件類型必須是圖片形式,并且文件大小不能超過允許上傳的***圖片值(MAX_IMAGE_SIZE為允許上傳的***圖片值)。