【问题标题】:Validating associated models in Rails在 Rails 中验证关联模型
【发布时间】:2014-02-08 23:44:10
【问题描述】:

我目前正在开发一个饮食跟踪应用程序。我有一个 FoodEntry 模型,其中每个实例引用另一个表中的单个 food,并且还引用另一个表中的 measurement 单元。

class FoodEntry < ActiveRecord::Base
  belongs_to :food
  belongs_to :measurement
  validates :food, presence: { message: 'must exist' }
  ...
end

这很好,但问题是 measurements 表中的每个条目都设置为(因为我正在处理外部数据)与某个 food 相关联,即测量属于食物,并且一种食物有多种尺寸:

class Food < ActiveRecord::Base
  has_many :measurements
  ...
end

class Measurement < ActiveRecord::Base
  belongs_to :food
  ...
end

我的问题是,验证我在 food_entry 中引用的特定 measurement 也是其 food.measurements 之一的正确方法是什么?

目前在我的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

此自定义验证有效,但我不确定它是否是最干净的方法。

我尝试这样做:

validates :measurement, inclusion: { in: food.measurements }

但这在 Rails 控制台中调用 FoodEntry.new(food_id: 1, measurement_id: 1) 时给我一个错误(实际 ids 无关紧要):

NameError: undefined local variable or method `food' for FoodEntry (no database connection):Class

在验证中使用in: self.food.measurements 没有任何区别。帮忙?

【问题讨论】:

    标签: ruby-on-rails validation activerecord ruby-on-rails-4 associations


    【解决方案1】:

    试试:

    validates :measurement, inclusion: { in: ->(record) { record.food.measurements } }
    

    validates 是在类上定义的方法,并在声明类时进行评估。通常,当包含值在程序启动之前已知(并且是静态的)时,传递值就足够了 - 验证器(在调用 validates 时创建)只是保存传递的对象并在验证时使用它。

    在您的情况下,包含值在创建验证器时是未知的(并且它们还取决于验证对象)。因此,您需要传递一个 lambda,以便验证器可以在运行时使用它来获取包含值。

    另请注意,验证器对象附加到类,而不是特定实例,因此 lambda 需要有记录参数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-23
      • 2018-10-02
      • 1970-01-01
      • 2012-05-11
      • 2016-06-18
      • 2023-03-30
      • 1970-01-01
      • 2012-12-25
      相关资源
      最近更新 更多