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