2015-12-17 34 views
-1

在我的Rails 4中,我有一個Post模型,我需要實現一個自定義驗證。Rails 4:undefined方法`facebook_copy_link'爲LinkValidator

繼建議in this questionin the documentation here,我已實現了以下的代碼:

#app/validators/link_validator.rb 

class LinkValidator < ActiveModel::Validator 
    def validate(record) 
    if record.format == "Link" 
     unless facebook_copy_link(record.copy) 
     record.errors[:copy] << 'Please make sure the copy of this post includes a link.' 
     end 
    end 
    end 
end 

#post.rb 
class Post < ActiveRecord::Base 
    [...] 
    include ActiveModel::Validations 
    validates_with LinkValidator 
    [...] 
end 

-----

UPDATE:該facebook_copy_link方法被定義如下:

class ApplicationController < ActionController::Base 
    [...] 
    def facebook_copy_link(string) 
    require "uri" 
    array = URI.extract(string.to_s) 
    array.select { |item| item.include? ("http" || "www") }.first 
    end 
    [...] 
end 

-----

當我運行應用程序,我得到以下錯誤:

NameError at /posts/74/edit 
uninitialized constant Post::LinkValidator 
validates_with LinkValidator 

任何想法,這裏有什麼問題?

-----

更新2:我忘了重新啓動服務器。

現在,我得到一個新的錯誤:

NoMethodError at /posts/74 
undefined method `facebook_copy_link' for #<LinkValidator:0x007fdbc717ba60 @options={}> 
unless facebook_copy_link(record.copy) 

有沒有一種辦法,包括在驗證這種方法嗎?

回答

1

除了成爲Rails驗證器類之外,LinkValidator也是一個Ruby類。所以你可以定義幾乎任何方法。

facebook_copy_link似乎並沒有被使用控制器實例的狀態,所以你可能只是輕鬆地移動方法付諸驗證類:我

require "uri" 

class LinkValidator < ActiveModel::Validator 
    def validate(record) 
    if record.format == "Link" 
     unless facebook_copy_link(record.copy) 
     record.errors[:copy] << 'Please make sure the copy of this post includes a link.' 
     end 
    end 
    end 

    private 

    def facebook_copy_link(string) 
    array = URI.extract(string.to_s) 
    array.select { |item| item.include? ("http" || "www") }.first 
    end 
end 

注意如何作出facebook_copy_link方法私有。這是一個很好的做法,因爲其他對象訪問的唯一方法是validate

作爲旁註,沒有必要將include ActiveModel::Validations放入ActiveRecord子類中。驗證已在ActiveRecord類中提供。

+0

感謝這非常有用的答案。如果您不介意的話,可以回答兩個簡單的問題:1.Facebook_copy_link實際上在PostsController中使用了兩次,這就是它現在位於ApplicationController中的原因:在給出這條新信息的情況下,您是否仍然會推薦移動它到驗證類? 2.我看到你在'class LinkValidator

+0

您*可以*將該方法移動到模型中,但是然後每個需要驗證的模型都必須定義該方法。另一種選擇是將其移入驗證器和控制器以外的類。至於'require',爲了清楚起見,我更願意將所有依賴項列在源文件的頂部。 :) – fivedigit

相關問題