2017-02-10 65 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 
尝试