如何通过StorageBox的code值设置Product的storage_box关联?
如何通过
code设置Rails模型的belongs_to关联 最符合Rails风格的实现方式是将code的解析与查找逻辑封装在StorageBox模型内,再在Product中自定义关联的赋值方法,既遵循单一职责原则,又保持代码的可维护性。
步骤1:在StorageBox中添加基于code的查找方法
因为code是由key和补零后的kind拼接而成,我们需要先拆分code,再匹配对应的记录:
class StorageBox < ApplicationRecord validates :key, presence: true, uniqueness: { scope: %i[kind] } validates :kind, presence: true def code "#{key}#{kind.to_s.rjust(4, '0')}" end # 根据code查找对应的StorageBox记录 def self.find_by_code(code) # 拆分code:截取前半部分为key,最后4位转为整数作为kind key = code[0...-4] kind = code[-4..-1].to_i find_by(key: key, kind: kind) end end
步骤2:在Product中自定义关联赋值方法
重写storage_box=方法,当传入字符串类型的code时,自动调用上面的查找方法获取关联对象:
class Product < ApplicationRecord belongs_to :storage_box def storage_box=(value) if value.is_a?(String) # 传入code字符串时,查找对应的StorageBox super(StorageBox.find_by_code(value)) else # 传入对象/ID时,沿用默认逻辑 super(value) end end end
测试使用
现在你可以直接通过code字符串设置关联:
Product.new(storage_box: '150001')
可选优化:处理找不到记录的情况
如果需要确保传入的code必须对应有效记录,可以将find_by替换为find_by!,这样当code不存在时会抛出ActiveRecord::RecordNotFound异常:
def self.find_by_code(code) key = code[0...-4] kind = code[-4..-1].to_i find_by!(key: key, kind: kind) end
内容的提问来源于stack exchange,提问作者Daniel Costa
相关产品推荐
相关产品推荐

