You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ActiveAdmin中手动触发Rails ActiveRecord模型校验?

实现方案

你可以在logo校验失败后,先手动给模型赋值表单提交的参数,再调用valid?触发全量校验,所有字段的错误会自动合并到@my_model.errors中,再渲染编辑页即可同时展示全部错误。

ActiveAdmin的参数赋值默认在before_action之后执行,所以你需要手动调用参数赋值逻辑,修改后的代码如下:

controller do
    before_action :prevent_save_if_invalid_logo, only: [:create, :update]

    private

    # Active Storage Validations display error messages but still attaches the file and persist the model
    # That's a known issue, which is solved in Rails 6
    # This is a workaround to make it work for our use case
    def prevent_save_if_invalid_logo
      return unless params[:my_model][:logo]

      file = params[:my_model][:logo]
      logo_valid = valid_logo_file_format(file) && valid_logo_aspect_ratio(file) && valid_logo_file_size(file)
      return if logo_valid

      # 手动赋值表单参数,触发全量校验
      @my_model.assign_attributes(permitted_params[:my_model])
      @my_model.valid?

      render 'edit' 
    end

    def valid_logo_aspect_ratio(file)
      width, height = IO.read(file.tempfile.path)[0x10..0x18].unpack('NN')
      
      valid = (2.to_f / 1).round(3) == (width.to_f / height).round(3)
      @my_model.errors[:logo] << "Aspect ratio must be 2 x 1" unless valid
      valid
    end

    def valid_logo_file_size(file)
      valid = File.size(file.tempfile) < 200.kilobytes
      @my_model.errors[:logo] << "File size must be < 200 kb" unless valid
      valid
    end

    def valid_logo_file_format(file)
      content_type = file.present? && file.content_type
      valid = content_type == "image/png"
      @my_model.errors[:logo] << "File must be a PNG" unless valid
      valid
    end
end

注意事项

  • 这里直接使用permitted_params[:my_model]获取ActiveAdmin配置好的白名单参数,不需要重复写参数过滤逻辑
  • 原代码中valid_logo_file_format方法返回值存在逻辑问题,非PNG格式时返回的是content_type字符串而非布尔值,会导致校验判断异常,已修正为统一返回布尔值
  • 手动调用assign_attributes和valid?不会触发ActiveStorage的附件持久化,不会出现校验失败但附件被保存的问题

内容的提问来源于stack exchange,提问作者Slth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 15:33:00