2016-11-02 2 views
0

私はいくつかのバリデーションを持つリンクモデルを持っています。 rspecスイート全体を実行すると、最後の検証で仕様が失敗します。「無効なURLを許可しないでください」モデル仕様中にレールモデルコールバックが実行されない

rspec spec/models/link_spec.rbを実行すると、モデル仕様がパスします。 validate_urlメソッドは呼び出されません。私のレールアプリは、モデル作成時のコールバックも無視しています。ここで

は私のモデルである:

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です。

答えて

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 

をしたり、またvalidateformatヘルパー使用することができます。

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

をあなたのspecファイルを実行すると、あなたのソリューションが動作する理由を私は知りません。私はドキュメントを読んで、before_*コールバックの:abortを返すことによって、saveアクションを中止し、falseを返すと述べています。

UPDATE:falseを返すことは保存されてからレコードを防ぐことはできません、あなたがエラーのコレクションにエラーを追加する必要があります。

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

がヒントをありがとう...それでも同じ問題に実行していますたとえvalidate文でurl_formatを指定したとしても。メソッドが呼び出され、uri.kind_of?(URI :: HTTP)行がfalseを返します。メソッド自体は、Railsコンソールから呼び出されるとfalseを返します。しかし、文を検証してもdbセーブトランザクションが発生しないようにはなりません。 –

+0

申し訳ありませんが、私はあなたが持っていたコードをよく読まなかったと思います。私は少し答えを更新してみましょう、私はあなたが持っている救助を削除します。 – fanta

関連する問題