fb_license

技術標籤

@selector (1) 初使化區塊 (1) 物件 (1) 物件導向 (2) 型別 (4) 封裝 (1) 流程控制 (1) 陣列 (3) 推論型別 (2) 實機測試 (1) 蓋索林(gasolin) (1) 模組 (1) 憑證 (1) 轉型 (1) 羅康鴻 (121) 類別 (1) 變數 (5) Accelerometer (1) ActiveRecord (1) Activity (1) AFNetworking (1) alloc (1) Android (3) Animation (1) App (1) App ID (1) APP上傳 (1) ASP.NET (1) AVAudioPlayer (1) block (1) C# (2) class (1) CLLocationManager (1) CLLocationManagerDelegate (1) CMMotionManager (4) Controller (1) delegate (1) DELETE語法 (1) Device Motion資料 (1) Dialog (1) DropDownList (1) dynamic language (2) Facebook SDK (9) FBRequest (5) FBRequestConnection (2) FMDB (1) Gesture Recognizers (6) GROUP BY (2) Gyro (1) HAVING (1) IBAction (1) IBOutlet (1) id (3) inheritance (1) init (1) Insert (1) instance variable (1) Interface Builder (1) iOS (70) iOS idea (7) iOS Introduction (1) Layout (1) Magnetometer (1) Menu (2) Method (2) MKMapView (1) MKPointAnnotation (1) MS SQL (5) Nil (1) NSArray (1) NSDictionary (1) NSError (1) NSFileManager & .plist (1) NSMutableArray (1) NSMutableDictionary (1) NSNotificationCenter (1) NULL (1) object (2) Objective-C (16) Objective-C idea (1) ORDER BY (1) Parameter (1) property (1) protocol (2) Provisioning (1) Proximate Sensor (1) Q and A (2) R類別 (1) Rails (9) RESTful SOA (9) Ruby (8) Scene (1) SEELECT (1) Segue (2) SEL (1) SELECT語法 (1) Shake (1) Simulator (1) SOA (8) SQL (6) SQL Server (5) SQL函數 (1) SQL彙總函數 SQL (1) SQLite (1) Storyboard (1) Style (1) Swift (1) Table (1) target & action (1) Theme (1) Toast (1) TRUNCATE TABLE語法 (1) UIActionSheet (1) UIActionSheetDelegate (1) UIActivityIndicatorView (1) UIAlertView (1) UIBarButtonItem (1) UIButton (1) UICollectionView (1) UICollectionViewDataSource (1) UIControl (9) UIDatePicker (1) UIImage (1) UIImagePickerController (2) UIImagePickerControllerDelegate (2) UIImageView (1) UILabel (1) UILongPressGestureRecognizer (1) UINavigationController (2) UIPanGestureRecognizer (1) UIPinchGestureRecognizer (1) UIProgressView (1) UIResponder (1) UIRotationGestureRecognizer (1) UISegmentedControl (1) UISlider (1) UIStepper (1) UISwipeGestureRecognizer (1) UISwitch (1) UITabBarController (1) UITableView (1) UITableViewDataSource (1) UITapGestureRecognizer (1) UITextField (1) UITextFieldDelegate (1) UITextView (2) UITextViewDelegate (1) UIToolBar (1) UIView (8) UIWebView (1) UPDATE語法 (1) var (2) VB.NET (7) View (4) WHERE子句 (1) XML (1)

2013/10/25

[Rails] RESTful SOA Part IV using Rails with Error Handler




我是工程師
我成功的透過Rails建立關於User管理的RESTful SOA的服務了,
怎麼連使用者名稱是空白都可以建立成功呢?!
我要怎麼加上這些驗證,並讓使用RESTful SOA的工程師知道發生了什麼事。


我是Error,你可以用類別定義我,
透過我定義各項不正確的操作
你只需要加上一些程式邏輯,
在發生錯誤時將我傳回即可。





在此我們針對建立user的方法create進行資料驗證的定義,定義的資料驗證如下:
  1. 姓名不為空白。
  2. 姓名至少為4個字元。
  3. 姓別必須為1(男性)或0(女性)。
在此將延用 [Rails] RESTful SOA Part III using Rails Routes & Controller & ActiveRecord 的範例作修改 - user_service_2_activerecord.zip


1.定義Error類別 - Error.rb

  • 將驗證的需求定義其代碼code與訊息message

  1. 姓名不為空白 => 代碼:0001,訊息:name is empty.
  2. 姓名至少為4個字元 => 代碼:0002,訊息:at least 4 chars for name.
  3. 姓別必須為1(男性)或0(女性) => 代碼:0003,訊息:gender must be 1(man) or 0(female).

  • 於{user}\user_service_2\app\models目錄下建立Error.rb

class Error end
  • 定義Error.error_list方法,其中以hash定義每個Error對應的code與message,並以陣列的方式保存回傳。在此特別加上9999代碼code的Error,以表示未知錯誤(未控管錯誤也於此列)

class Error #透過Hash儲存 def Error.error_list [ {:code => "0001", :message => "name is empty."}, {:code => "0002", :message => "at least 4 chars for name."}, {:code => "0003", :message => "gender must be 1(man) or 0(female)"}, {:code => "9999", :message => "unknow error"} ] end end
  • 定義Error.find(code)方法,透過代碼code的傳入找出與此相同代碼code的Error hash
class Error def Error.find(code) #透過Array的select方法,找出Hash中:code key對應值為參數code的error hash物件 @find_result = Error.error_list.select {|e| e[:code] == code} #將找到的第1個hash回傳 #注意,因:code皆不重複,所以只會找到一個 #最後在使用hash,以:error key對應到這個error { :error => @find_result.first} end #略過一些程式 end

2. 加入驗證邏輯 - create方法

  • 開啟{user}\user_service_2\app\controller\users_controller.rb
  • 針對create方法,依序加入驗證資料的邏輯程式,並在檢驗資料未通過時,透過Error.find(code),取得對應的Error物件,並以json格式回傳。]

def create #檢查資料 #1. 姓名為空 if (params[:name].empty?) #找出表示代碼為"0001"錯誤訊息 @error = Error.find("0001"); #回傳此錯誤訊息 render json: @error return end #2. 姓名長度小於4,錯誤代碼0002 if (params[:name].length < 4) #找出表示代碼為"0002"錯誤訊息 @error = Error.find("0002"); #回傳此錯誤訊息 render json: @error return end #3. 性別不為0或1,錯誤代碼0003 if ( not (params[:gender] == "0" || params[:gender] == "1")) #找出表示代碼為"0003"錯誤訊息 @error = Error.find("0003"); @error[:details] = params[:gender] #回傳此錯誤訊息 render json: @error return end #透過new建立user物件 @user = User.new #讀取傳入的資料,並設定在user物件的對應欄位上 #這些欄位皆是透過rails generate model時所建立的 @user.name = params[:name] @user.age = params[:age] @user.gender = params[:gender] #透過save方法將資料存入, #若成功則會回傳true if (@user.save) #存檔成功回傳user資料 render json: @user else#存檔失敗,回傳錯誤資訊 @error = Error.find("9999"); @error[:details] = @user.errors render @error end end



4. 啟動伺服器 - rails server
  • 開啟終端機,切換到{user}\user_service_2目錄
  • 輸入rails server,透過rails server啟動伺服器,其預設的port為3000:


3. 測試 - Postman
  • 測試1 - 姓名為空白:
    • URI:http://localhost:3000/users
    • HTTP Method:PUT
    • Data:
      • name:
      • age:31
      • gender:1

  • 測試2 - 姓名長度小於4個字元:
    • URI:http://localhost:3000/users
    • HTTP Method:PUT
    • Data:
      • name:abc
      • age:31
      • gender:1

  • 測試1 - 性別不為1(男性)或0(女性):
    • URI:http://localhost:3000/users
    • HTTP Method:PUT
    • Data:
      • name:khlo
      • age:31
      • gender:man
當然,您也可以為users_controller.rb檔中的其他操作R(read與read_all方法)、U(update方法)與D(delete方法),作資料的驗證,以回傳適當的錯誤代碼,讓使用您元件的程式設計人員可依代碼判斷是何種錯誤,進而告知使用者更正。


  • 以下範例加入了R的read方法判斷使用者編號id是否存在,若存在才讀取資料,否則回傳錯誤代碼 0004,表示id不存在。


class Error attr_accessor :code attr_accessor :message def Error.find(code) #透過Array的select方法,找出Hash中:code key對應值為參數code的error hash物件 @find_result = Error.error_list.select {|e| e[:code] == code} #將找到的第1個hash回傳 #注意,因:code皆不重複,所以只會找到一個 @find_result.first end #透過Hash儲存 def Error.error_list [ {:code => "0001", :message => "name is empty."}, {:code => "0002", :message => "at least 4 chars for name."}, {:code => "0003", :message => "gender must be 1(man) or 0(female)"}, {:code => "0004", :message => "user id is not exist."}, {:code => "9999", :message => "unknow error"} ] end end

class UsersController < ApplicationController def read_all #透過find方法與參數:all找出所有的user資料 @users = User.find(:all) #回傳所有的user資料 render json: @users end def read #判斷使用者編號id是否存在 if(not User.exists?(params[:id])) #找出表示代碼為"0004"錯誤訊息 @error = Error.find("0004"); #回傳此錯誤訊息 render json: @error return end #依id回傳對應的資料 @user = User.find(params[:id]) #回傳user資料 render json: @user end #略過一些程式 end

  • 最後為U的update方法加上判斷使用者編號id是否存在,與相同於建立使用者的資料驗證。

class UsersController < ApplicationController #略過一些程式 def update #判斷使用者編號id是否存在 if(not User.exists?(params[:id])) #找出表示代碼為"0004"錯誤訊息 @error = Error.find("0004"); #回傳此錯誤訊息 render json: @error return end #透過find方法找出特定使用者編號id的user @user = User.find(params[:id]) #更新資料 @user.name = params[:name] @user.age = params[:age] @user.gender = params[:gender] #透過save方法更新資料 if (@user.save) #回傳更新後的user資料 render json: @user else#更新失敗,回傳錯誤資訊 @error = Error.find("9999"); @error[:details] = @user.errors render json: @error end end #略過一些程式 end


範例程式:user_service_2_error_handler_full.zip