Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ruby-on-rails-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails Rails 3.1+;设计1.4.9:为什么';ActiveRecord是否捕获失败的保存?_Ruby On Rails_Ruby On Rails 3_Activerecord_Ruby On Rails 3.1 - Fatal编程技术网

Ruby on rails Rails 3.1+;设计1.4.9:为什么';ActiveRecord是否捕获失败的保存?

Ruby on rails Rails 3.1+;设计1.4.9:为什么';ActiveRecord是否捕获失败的保存?,ruby-on-rails,ruby-on-rails-3,activerecord,ruby-on-rails-3.1,Ruby On Rails,Ruby On Rails 3,Activerecord,Ruby On Rails 3.1,更新:我正在使用Desive 1.4.9进行身份验证,我的Desive生成的用户模型似乎没有捕获数据库在尝试创建一个新用户时抛出的异常,该用户的电子邮件地址已存在于数据库中。在遵循cicloon的建议(参见下面的回复)之后,我创建新用户的代码是 class Api::RegistrationsController < Api::BaseController respond_to :json def create user = User.new(params[:user]

更新:我正在使用Desive 1.4.9进行身份验证,我的Desive生成的用户模型似乎没有捕获数据库在尝试创建一个新用户时抛出的异常,该用户的电子邮件地址已存在于数据库中。在遵循cicloon的建议(参见下面的回复)之后,我创建新用户的代码是

class Api::RegistrationsController < Api::BaseController

  respond_to :json

  def create
    user = User.new(params[:user])
    user.ensure_authentication_token! 

    if user.valid?
        user.save
        render :json=> user.as_json(:auth_token=>user.authentication_token, :email=>user.email, :user_id=>user.id), :status=>201
        return
    else
        warden.custom_failure!
        render :json=> user.errors, :status=>422
    end
  end
end
这是用户模型

class User < ActiveRecord::Base
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable, :token_authenticatable

  attr_accessible :email, :password, :password_confirmation, :remember_me, :authentication_token 

  validates_uniqueness_of :email

  def ensure_authentication_token!   
    reset_authentication_token! if authentication_token.blank?   
  end  

  def as_json(options={})
    super(:only => [:email, :authentication_token, :id])
  end

end
如何让我的代码返回带有错误描述的422


非常感谢你的智慧

我认为您可能需要将验证添加到您的用户模型中

validates_uniqueness_of :email

我又读了你的帖子,现在我知道那里发生了什么。您有一个数据库索引,Rails不知道,因此当您创建@user.save时,数据库会抛出一个Rails未捕获的异常

也就是说,您有两个选择:

1.)在Rails中捕获异常:

begin
  user.save
  render :json=> user.as_json(:auth_token=>user.authentication_token, :email=>user.email, :user_id=>user.id), :status=>201

rescue
  warden.custom_failure!
  render :json=> user.errors, :status=>422
end
2.)将验证添加到您的模型并检查用户。有效吗?:

在您的用户模型上:

validates_uniqueness_of :email
在控制器上:

  if user.valid?
      user.save
      render :json=> user.as_json(:auth_token=>user.authentication_token, :email=>user.email, :user_id=>user.id), :status=>201
      return
  else
      warden.custom_failure!
      render :json=> user.errors, :status=>422
  end

我会将其包装在异常处理程序中。试着这样做:

class Api::RegistrationsController < Api::BaseController

  respond_to :json

  def create
    user = User.new(params[:user])

    status = nil
    json   = nil

    begin
      user.ensure_authentication_token!
      user.save!
      status = 201
      json   = {
        :auth_token => user.authentication_token,
        :email      => user.email,
        :user_id    => user.id
      }
    rescue StandardError => e
      case e
      when ActiveRecord::StatementInvalid, ActiveRecord::RecordNotUnique
        # ActiveRecord::StatementInvalid -> Raised by SQLite Adapter
        # ActiveRecord::RecordNotUnique  -> Raised by Postgres Adapter
        user.errors[:email] = 'already taken'
      end

      warden.custom_failure!

      status = 422
      json   = user.errors
    end

    render :json => json, :status => status
  end
end
class Api::RegistrationControlleruser.authentication_token,
:email=>user.email,
:user_id=>user.id
}
营救标准错误=>e
案例e
当ActiveRecord::StatementInvalid时,ActiveRecord::RecordNotUnique
#ActiveRecord::StatementInvalid->由SQLite适配器引发
#ActiveRecord::RecordNotUnique->由Postgres适配器引发
user.errors[:email]=“已拍摄”
结束
典狱长,你失败了!
状态=422
json=user.errors
结束
呈现:json=>json,:status=>status
结束
结束

您能提供一些日志吗?我想你的索引可能还没有创建,所以保存并不是真的失败。有什么特别的日志吗?除了我上面发布的SQLite3错误之外,服务器日志实际上没有显示太多内容。有什么方法可以让我查看为我的模型创建的标识吗?谢谢,cicloon,我尝试了两种建议,但都没有成功。请查看我的更新问题以查看我的当前代码。再次感谢你的帮助!没关系,我发现了问题。我必须移动调用以确保if user.valid下的\u身份验证\u令牌?行,该修复的ituser.save不会引发异常。user.save!将引发验证异常和数据库异常。看到postgres和sqlite驱动程序以不同的方式报告异常,我有点难过。还要注意的是,我还没有测试过这个w/MySQL,它可能也会做一些完全不同的事情。我还要注意的是,这并不是一个真正针对设计的问题。归根结底,db索引是唯一可以可靠地强制唯一性的东西。Sebi提到的验证器在大多数情况下都能很好地工作,但不是所有情况。最终,您必须处理db异常以捕获所有场景。
  if user.valid?
      user.save
      render :json=> user.as_json(:auth_token=>user.authentication_token, :email=>user.email, :user_id=>user.id), :status=>201
      return
  else
      warden.custom_failure!
      render :json=> user.errors, :status=>422
  end
class Api::RegistrationsController < Api::BaseController

  respond_to :json

  def create
    user = User.new(params[:user])

    status = nil
    json   = nil

    begin
      user.ensure_authentication_token!
      user.save!
      status = 201
      json   = {
        :auth_token => user.authentication_token,
        :email      => user.email,
        :user_id    => user.id
      }
    rescue StandardError => e
      case e
      when ActiveRecord::StatementInvalid, ActiveRecord::RecordNotUnique
        # ActiveRecord::StatementInvalid -> Raised by SQLite Adapter
        # ActiveRecord::RecordNotUnique  -> Raised by Postgres Adapter
        user.errors[:email] = 'already taken'
      end

      warden.custom_failure!

      status = 422
      json   = user.errors
    end

    render :json => json, :status => status
  end
end