【问题标题】:rails model callback not running during model spec在模型规范期间没有运行rails模型回调
【发布时间】:2016-11-02 16:13:28
【问题描述】:

我有一个带有多个验证的链接模型。当我运行整个 rspec 套件时,规范在最后一次验证“不应允许无效的 url”时失败

但是,当我运行 rspec spec/models/link_spec.rb 时,模型规范通过了。 validate_url 方法永远不会被调用。我的 rails 应用程序也忽略了模型创建时的回调。

这是我的模型:

require 'uri'

class Link < ApplicationRecord
  belongs_to :user

  validates :url, presence: true
  validates :title, presence: true
  validates :read, absence: false
  validates :user_id, presence: true

  before_save :validate_url

  private

  def validate_url
    require 'pry'; binding.pry
    uri = URI.parse(self.url)
    uri.kind_of?(URI::HTTP)
  rescue URI::InvalidURIError
    false
  end
end

和我的模型规格:

require 'rails_helper'

describe Link, type: :model do
  it { should validate_presence_of :url }
  it { should validate_presence_of :title }
  it { should validate_presence_of :user_id }

  it "should not allow an invalid url" do
    link = Link.create({
      title: "new link",
      url: "garbage",
      user_id: 1
    })

    expect(link.valid?).to be_falsey
    expect(link.save).to be_falsey
  end
end

任何想法为什么不访问回调方法?我在 Rails 5.0.0.1 和 RSpec 3.5.4

【问题讨论】:

    标签: ruby-on-rails activerecord rspec model ruby-on-rails-5


    【解决方案1】:

    before_* 方法主要用于准备数据,或在操作发生之前执行其他操作。验证需要在 ActiveRecord 对象的validation 步骤中进行。因此,我将删除该代码并将其放在 validate 句子中。

    你可以使用类似的东西:

    validate :url_format
    ...
    private
    def url_format
      uri = URI.parse(self.url)
      uri.kind_of?(URI::HTTP)
    rescue URI::InvalidURIError
      errors.add(:url, 'Url is invalid')
    end
    

    或者您也可以使用validate format 助手:

    validate :url, format: { with: URI::regexp(%w(http https)) }
    

    我不知道为什么您的解决方案在您运行规范文件时有效。我阅读了文档,它指出通过在任何 before_* 回调中返回 :abort 将中止 save 操作并返回 false。

    更新:返回false 不会阻止记录被保存,您需要将错误添加到错误集合中:

    private
    def url_format
      uri = URI.parse(self.url)
      errors.add(:url, 'Url is invalid') unless uri.kind_of?(URI::HTTP)
    end
    

    【讨论】:

    • 感谢您的提示...但即使在验证句中使用 url_format,仍然会遇到同样的问题。正在调用该方法并且 uri.kind_of?(URI::HTTP) 行返回 false。当从 Rails 控制台调用时,该方法本身返回 false。但是,验证语句不会阻止数据库保存事务的发生
    • 对不起,我想我没有读好你的代码。让我稍微更新一下答案,我会删除你的救援。
    猜你喜欢
    • 2019-11-18
    • 1970-01-01
    • 2015-05-13
    • 1970-01-01
    • 2015-08-18
    • 1970-01-01
    • 1970-01-01
    • 2012-12-28
    • 1970-01-01
    相关资源
    最近更新 更多