【问题标题】:Rails - How to handle record create with has_many association errorRails - 如何使用 has_many 关联错误处理记录创建
【发布时间】:2017-03-30 15:05:39
【问题描述】:

我在尝试处理具有 has_many 关联的模型上的 #create 请求时遇到问题,其中传入的 ID 之一不属于现有记录。

测试请求:

post authors_path, params: { book_ids: [-1] }

控制器方法:

def create
  @author= Author.create params
end

型号:

class Author
  has_many :books
end

这会导致出现ActiveRecord::RecordNotFound 错误。

问题如下:

我已经从ActiveRecord::RecordNotFound 错误中解救出来,并在我的ApplicationController 中回复404 Record Not Found,因为当用户尝试GETPATCHPUT 或@ 时,通常会出现此类错误987654333@ 一条不存在的记录,例如,get author_path(-1)。我宁愿避免将rescue 子句移到#show#create 等方法上,因为我有很多控制器,导致大量重复代码。

我想保持我的记录和关联创建原子,这似乎是做到这一点的最佳方式,但我也想在上述情况发生时回复400 Bad Request。处理这种情况的最佳方法是什么?

更新

经过更多研究,我编写了一个快速自定义验证,用于验证所有传入 book_ids 的记录是否存在

class Author < ApplicationRecord  
  validate :books_exist  

  def books_exist  
    return if book_ids.blank?  
    Book.find book_ids
  rescue ActiveRecord::RecordNotFound => e  
    errors.add e.message  
  end  
end

这似乎不起作用,因为即使实例化一个新的 Author 实例而不将其保存到数据库中也会引发 ActiveRecord::RecordNotFound 错误:

> Author.new(association_ids: [-1])
  Book Load (2.3ms) SELECT `books`.* FROM `books` WHERE `books`.`id` = -1
ActiveRecord::RecordNotFound: Couldn't find Book with 'id'=[-1]
  from ...

问题似乎是ActiveRecord 在进行任何验证之前尝试为传入的book_id 查找记录。有没有办法挽救这个错误?对于这个特定问题,似乎没有太多解决方法。

【问题讨论】:

    标签: ruby-on-rails activerecord


    【解决方案1】:

    在 StackOverflow 之外向我建议的两个解决方案如下:

    1. 挽救每个控制器动作中的错误

      class AuthorsController
        def create
          @author = Author.create(params)
          render json: @author
        rescue ActiveRecord::RecordNotFound => e
          render json_error_message
        end
      end
      
    2. ApplicationController中创建一个通用操作

      class ApplicationController
        def create(model)
          instance_variable_set("@#(model.class.name}", model.create(params)
        rescue ActiveRecord::RecordNotFound => e
          render json_error_message
        end
      end
      
      class AuthorsController
        def create
          super(Author)
        end
      end
      

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-08
      • 1970-01-01
      • 2011-09-27
      • 2014-02-27
      相关资源
      最近更新 更多