【问题标题】:Validate :on with custom method in Rails Controller验证:在 Rails 控制器中使用自定义方法
【发布时间】:2020-08-06 15:16:21
【问题描述】:

我想对以下路由做一个放置/补丁,作为回报,它会调用 bar 控制器并调用它的 update_premium 方法: put '/bar/premium', to: 'bars#update_premium'

但是,无论何时调用 .save 或 .valid?/.valid,该方法都应在模型本身中调用验证检查。

bar.rb

class Bar < ApplicationRecord
    belongs_to :city
    validate :validate_premium_bars, on: :create
    validate :validate_premium_bars, on: :update_premium

    def allow
        @allow_change = true
    end

    private
    def validate_premium_bars
        return unless self.city
        unless @allow_change
            if self.city.bars.where(:is_premium => true).count >= 5
                errors.add("...")
            end
        end
    end
end

bars_controller.rb

def update_premium
        @bar = Bar.find(params[:id])
        if @bar.save
            ...
        else
            render json: @bar.errors.full_messages, status: 400
        end
end

当我使用on: :update 时它可以工作,但是控制器中的自定义方法(例如on: :update_premium)不能与“on:”符号一起使用。

我该如何解决这个问题?我想将 update 方法保留在控制器中,以进行真正的完整模型更新,而不仅仅是触发模型的一个属性。

【问题讨论】:

  • 如何更新update_premium 方法中的值? Rails 模型验证回调通常应该在 update 上调用,而不仅仅是控制器中的 update 方法。
  • @anonn023432 就像这样,例如:@bar.is_premium = !@bar.is_premium

标签: ruby-on-rails ruby api validation


【解决方案1】:

考虑到这个问题的情况,我实际上建议将验证添加为:

validate :validate_premium_bars

所以每次运行 valid?save 时它都会运行,而不是为 createupdate 添加特定条件。

如果您出于某种原因想要单独添加它。您可以添加验证以运行 update,并在值检查后使用 update 调用或调用 valid? 更新实际属性,以确保记录通过验证

【讨论】:

  • 谢谢,这确实是解决我问题的最明显和最简单的方法。
【解决方案2】:

问题是update 控制器动作没有映射到模型动作。一个指端点,另一个指模型生命周期中的事件。 查看official documentation 关于验证选项。

您可以创建自定义条件验证,以便在每次更改模型时运行。例如:

  validate :validate_premium_bars, if: :allowed_chage?
 
  def allowed_chage?
    @allowed_chage
  end

soruce

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-28
    • 1970-01-01
    • 2021-11-21
    • 2011-04-11
    相关资源
    最近更新 更多