2017-02-10 79 views
0

我正在嘗試創建一個Web API,允許通過電子郵件或電話號碼創建FriendShipRails Web API拋出錯誤

class Api::FriendshipsController < Api::BaseController 

    respond_to :json 

    def create 
     friend = User.where("email = ? OR phone_number = ?", params[:emailOrPhone], params[:emailOrPhone]).first # create a friend by email or phone_number 
     if friend.valid? # check if the friend exists, if it does we create our new friendship 
      friendship = Friendship.new 
      friendship.user = current_user 
      friendship.friend = friend 
      if friendship.valid? # check if friendship is valid 
       friendship.save # if it is, we save and return a success JSON response 
       render json: {created: true}, status: 200 
      else # if it's not a valid friendship, we display a error JSON response 
       render json: {created: false}, status: 400 
      end 
     end 
    end 
end 

這裏是我的FriendShip模型

class Friendship < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :friend, :class_name => "User" 

    validates_uniqueness_of :user_id, scope: :friend_id, :message => '%{friend_id} is already a friend' 

    validate :check_friend_and_user # prevent user trying to add him/herself as friend. 

    def check_friend_and_user 
     errors.add(:friend, "can't be the same as user") if user == friend 
    end 
end 

每當唯一性約束被侵犯,錯誤missing interpolation argument :friend_id in "%{friend_id} is already a friend" ({:model=>"Friendship", :attribute=>"User", :value=>2} given),錯誤代碼500

如何使它不會引發錯誤,而是繼續給出狀態代碼的'失敗json響應'400

我希望此API的調用者知道他們正在嘗試添加已經是朋友的人。取回狀態代碼500和一堆html似乎並不能唯一標識它。所以我想以JSON的形式拋出一個錯誤並且狀態200

回答

1

你似乎試圖做的是確定朋友是否已經通過友誼類與用戶關聯。您可以通過用戶對象上的has_many:friendships關聯進行簡化。

此外,您通過電子郵件或手機查找的方式是IMO不必要地模棱兩可,如果您想爲其他目的單獨跟蹤一個或另一個目標,將會出現問題。你似乎希望這樣做,因爲你已經將它們分解爲單獨的數據庫列。我想你可以把兩個表單輸入電子郵件或電話號碼,並只傳遞給控制器​​。如果你只有一個,那麼你可以確定表單用Javascript提交什麼。

在這種情況下,您最好將表單類型的標識符與表單中的初始數據一起發送,以便您可以查找其中一個或另一個。所以你的表單會明確地發送列查找標識符,例如在PARAMS將相當於紅寶石哈希

{friendship: {email: "[email protected]"}}

與在PARAMS那麼你可以做你的這段代碼

# assuming you're passing via a params hash that would look like  
# one or the other of the following 
# {friendship: {email: "[email protected]"}} 
# {friendship: {phone_number: "123-123-1234"}} 
def create 
    if current_user.friendships.find_or_create_by(friendship_params) 
    render json: {created: true}, status: 200 
    else # if it's not a valid friendship, we display a error JSON response 
    render json: {created: false}, status: 400 
    end 
end 

protected 


def friendship_params 
    require(:friendship).permit(:email, :phone_number) 
end 
嘗試