2016-02-26 48 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而始终是唯一的。 –

相关问题