Ruby On Rails:如何在自定义before_validation方法中传递参数
问题
我有一个需要传入参数的私有方法,代码如下:
private def file_type(file) # 代码内容 end
在同一模型文件中,我尝试了以下几种方式调用该方法,但均不生效:
has_one_attached :image, dependent: :destroy has_one_attached :image1, dependent: :destroy before_validation :file_type, file: :image before_validation :file_type, file: :image1 before_validation :file_type(params[:image]) before_validation :file_type(params[:image1])
请问是否存在无需创建新验证类文件即可传递参数的方法?
解决方法
当然可以,不用新建验证类也能实现传参调用,以下是两种可行方案:
方案一:使用Lambda(匿名函数)直接传参
Rails的回调支持传入Lambda表达式,你可以在Lambda里直接调用目标方法并传入模型的附件属性:
has_one_attached :image, dependent: :destroy has_one_attached :image1, dependent: :destroy before_validation -> { file_type(image) } before_validation -> { file_type(image1) }
Lambda会在验证回调触发时执行,此时处于模型实例的上下文,可以直接通过image、image1获取对应的附件对象,传递给file_type方法。
方案二:编写包装方法
为每个附件属性写一个对应的私有包装方法,在包装方法里调用file_type并传入对应参数,然后将包装方法作为回调:
has_one_attached :image, dependent: :destroy has_one_attached :image1, dependent: :destroy before_validation :validate_image_type before_validation :validate_image1_type private def validate_image_type file_type(image) end def validate_image1_type file_type(image1) end def file_type(file) # 代码内容 end
这种方式更直观,当需要验证的附件数量较多时,代码可读性更强。
补充:之前写法失效的原因
before_validation :file_type, file: :image:这种写法的file: :image是回调的选项参数,但默认情况下回调方法不会接收这些选项,所以file_type方法无法获取到传入的file参数。before_validation :file_type(params[:image]):这种写法会在类加载阶段就执行file_type(params[:image]),而不是在验证回调时触发;同时类加载阶段不存在params对象,所以必然失效。
内容的提问来源于stack exchange,提问作者Ese10
相关产品推荐
相关产品推荐

