2016-02-26 68 views
0

我有兩個符號,其值由用戶設置。ActiveRecord驗證:一個符號的最大長度爲值減去另一個符號的長度

我需要驗證它們的長度。每個符號的最大長度需要是32減去另一個符號的長度。

我已經寫得像這麼遠,但這是行不通的。有沒有人有任何建議,這可以如何工作?

validates :id, presence: true, uniqueness: { scope: :name }, length: { maximum: 32 - :name.length } 
validates :name, uniqueness: { scope: :id }, length: { maximum: 32 - :id.length } 

注意:我只是一個畢業生,所以我有很大的機會完成這個錯誤,因爲我仍然在學習,並且還沒有真正理解符號。

回答

0

聽起來像是你在這裏需要自定義驗證:

validates :id, presence: true, uniqueness: { scope: :name } 
validates :name, uniqueness: { scope: :id } 
validate :name_and_id_max_length 

def name_and_id_max_length 
    if (id || '').length + (name || '').length > 32 
    errors.add(:base, "id and name combined must be 32 or fewer characters") 
    end 
end 

BTW:通常在Rails的id是一個整數,但你似乎是把它當作一個字符串。這表明還有其他一些困惑。

另外:id.length是無效的Ruby。在這些validates聲明中,您正在調用方法,所以沒有帶有id的實例。要對實際值進行算術運算,您需要一個proc。 Rails不支持這裏的這個據我所知,但在其他情況下它嵌入你聲明在類級別每個實例計算的片段一個有用的模式:

validates :name, length: { maximum: proc { 32 - id.length } } 

例如,對於一個真實的例子:

scope :recent, -> { where("created_at > ?", 24.hours.ago) } 
+0

我想你應該寫'id.to_s'。 –

+0

'id'驗證的唯一性是不必要的.. :)'name'上的唯一性很好..不需要使用'id'作爲範圍.. –

+1

作爲@Arup asys,如果'id'實際上是您的主鍵,正如Rails中的正常情況一樣,在'name'的唯一性約束中添加'{scope:id}'是錯誤的,因爲兩個相同的名稱由於其不同的id而始終是唯一的。 –