Rails after_initialize只在“新”
我有以下2个模型
class Sport < ActiveRecord::Base has_many :charts, order: "sortWeight ASC" has_one :product, :as => :productable accepts_nested_attributes_for :product, :allow_destroy => true end class Product < ActiveRecord::Base belongs_to :category belongs_to :productable, :polymorphic => true end
没有产品的运动就不能存在,所以在我的sports_controller.rb
我有:
def new @sport = Sport.new @sport.product = Product.new ... end
我尝试使用after_initialize
将产品的创build移动到运动模型:
after_initialize :create_product def create_product self.product = Product.new end
我很快就知道,每当一个模型被实例化时(即从一个find
调用), after_initialize
调用after_initialize
。 所以那不是我正在寻找的行为。
我应该如何模拟所有sport
都有product
的要求?
谢谢
把逻辑放在控制器中可能是你所说的最好的答案,但你可以通过执行以下after_initialize
来获得after_initialize
的工作:
after_initialize :add_product def add_product self.product ||= Product.new end
这样,只有在没有产品存在的情况下才设置产品。 这可能不值得花费和/或不如控制器中的逻辑清楚。
编辑:根据莱恩的回答,在性能方面,以下可能会更好:
after_initialize :add_product def add_product self.product ||= Product.new if self.new_record? end
如果你做self.product ||= Product.new
它会每次search一个产品,因为它需要检查是否为零。 因此它不会做任何急切的加载。 为了做到这一点,只有在创build新logging时,您可以在设置产品之前简单地检查它是否是新logging。
after_initialize :add_product def add_product self.product ||= Product.new if self.new_record? end
我做了一些基本的基准testing,并检查if self.new_record?
似乎没有以任何明显的方式影响性能。
当然, after_initialize :add_product, if: :new_record?
这里是最干净的方式。
保持add_product函数的条件
而不是使用after_initialize
,那么after_create
呢?
after_create :create_product def create_product self.product = Product.new save end
这看起来像会解决你的问题?
看起来你很亲密 你应该能够完全消除after_initialize调用,但首先我相信如果你的运动模型与你所指出的产品有“has_one”的关系,那么你的产品模型也应该“belongs_to”运动。 将其添加到您的产品型号
belongs_to: :sport
下一步,你现在应该能够像这样实例化一个运动模型
@sport = @product.sport.create( ... )
这是基于Ruby on Rails指南中关联基础知识的信息,如果我不完全正确,您可以通读这些信息
你应该重写初始化方法
class Sport < ActiveRecord::Base # ... def initialize(attributes = {}) super self.build_product self.attributes = attributes end # ... end
从数据库加载logging时,永远不会调用Initialize方法。 请注意,在上面的代码中,属性是在产品生成后分配的。 在这种设置中,属性分配会影响创build的产品实例。