[英]Validating associated models in Rails
I am currently working on a diet tracking app. 我目前正在研究饮食跟踪应用程序。 I have a FoodEntry model where each instance references a single
food
from another table, and also references a unit of measurement
from yet another table. 我有一个FoodEntry模型,其中每个实例引用另一个表中的单个
food
,并且还引用另一个表中的measurement
单位。
class FoodEntry < ActiveRecord::Base
belongs_to :food
belongs_to :measurement
validates :food, presence: { message: 'must exist' }
...
end
That works fine, but the thing is that each entry in the measurements
table is set up (because I'm working with external data) to be associated with a certain food
, ie a measurement belongs to a food, and a food has many measurements: 这很好,但问题是
measurements
表中的每个条目都已设置(因为我正在使用外部数据)与某种food
相关联,即测量属于食物,食物有很多测量:
class Food < ActiveRecord::Base
has_many :measurements
...
end
class Measurement < ActiveRecord::Base
belongs_to :food
...
end
My question is, what is the correct way to validate that the specific measurement
I'm referencing in a food_entry
is also one of its food.measurements
? 我的问题是,验证我在
food_entry
引用的具体measurement
也是其food.measurements
measurement
的正确方法是什么?
Currently in my FoodEntry
model I'm doing this: 目前在我的
FoodEntry
模型中,我这样做:
validate :measurement_must_be_associated
def measurement_must_be_associated
unless food.measurements.include? measure
errors.add(:measurement, 'is not associated with that food')
end
end
This custom validation works, but I'm not sure it's the cleanest way to do it. 这个自定义验证有效,但我不确定这是最干净的方法。
I attempted to do this instead: 我尝试这样做:
validates :measurement, inclusion: { in: food.measurements }
but this gives me an error when calling FoodEntry.new(food_id: 1, measurement_id: 1)
in the rails console (actual id
s are irrelevant): 但是当在rails控制台中调用
FoodEntry.new(food_id: 1, measurement_id: 1)
时,这会给我一个错误(实际id
不相关):
NameError: undefined local variable or method `food' for FoodEntry (no database connection):Class
Using in: self.food.measurements
in the validation made no difference. in: self.food.measurements
在验证中没有区别。 Help? 救命?
Try: 尝试:
validates :measurement, inclusion: { in: ->(record) { record.food.measurements } }
validates
is a method defined on a class, and is being evaluated when a class is declared. validates
是在类上定义的方法,在声明类时进行评估。 Normally, when inclusion values are known before program starts (and are static), passing value is sufficient - validator (which is being created when validates
is called) simply saves the passed object and uses it when validating. 通常,当包含值在程序启动之前已知(并且是静态的)时,传递值就足够了 - 验证器(在调用
validates
时创建)只是保存传递的对象并在验证时使用它。
In your case the inclusion values are unknown at the point when validator is created (and they also depends on the validating object). 在您的情况下,包含值在创建验证器时是未知的(并且它们还取决于验证对象)。 Hence, you need to pass a lambda, so validator can use it to get inclusion values during a runtime.
因此,您需要传递一个lambda,因此验证器可以使用它来在运行时获取包含值。
Note also, that validator object is attached to a class, not to a particular instance, so lambda needs to have record param. 另请注意,验证器对象附加到类,而不是特定实例,因此lambda需要具有记录参数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.