Rails - 如何验证关联模型的状态作为父模型的状态

时间:2014-11-12 22:04:50

标签: ruby-on-rails api activerecord transactions

我正在使用rails构建一个用于ember webapp后端的API。我们有一个名为'Palette'的模型,它有许多与之相关的颜色。由于构建ember应用程序的方式,我们将删除颜色,并在更新调色板时用新对象替换它们。挑战在于,如果颜色的新状态不再有效,我们已经删除了旧颜色并且无法返回到原始状态。到目前为止,我们唯一的解决方案是在调色板控制器的更新方法中创建一个事务,如果任何新的颜色创建失败或调色板失败,将抛出异常。虽然这个解决方案有效,但感觉有点笨拙。有更优雅的解决方案吗?

class PalettesController < BaseController

  def update
    ActiveRecord::Base.transaction do
      begin
        palette = Palette.find params[:id]
        palette.destroy_colors
        params[:palette][:colors].each do |color|
        Color.create! palette: palette, 
                    name: color[:name], 
                    cmyk: color[:cmyk],
                    color_type: color[:color_type]
        end
        return render json: palette.errors, 
          status: :unprocessable_entity unless palette.save!
      rescue
        return render json: { error: 'Unable to process the request' }.to_json, 
          status: :unprocessable_entity
      end
      render json: palette, status: 200
    end
  end

end 

1 个答案:

答案 0 :(得分:0)

我认为您可以像这样解决它,将以下代码添加到调色板模型中:

validate :all_colors_valid  

def all_colors_valid
  colors.each do |color|
    errors.add('Color', 'invalid') unless color.valid?
  end
end

每当您保存ActiveRecord对象时,它都会经历以下链接中描述的一系列步骤。其中一个是验证,可以是rails标准验证,也可以编写自己的自定义验证。

如果正在保存的对象在验证阶段后出现任何错误,则会中止保存操作,并且不会对数据库进行任何更改。

发送到errors.add的两个参数是包含错误的列的名称以及问题所在。你可以通过说出哪种颜色是坏的或类似的东西来使这更好。

请注意,在此验证完成后,不会创建新颜色。它只保证它们都可以毫无错误地保存。

如果您希望自动通过调色板模型保存它们,我建议您在after_save操作中执行此操作。

http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html