Tyl*_*itt 51 model ruby-on-rails nested-attributes
我有以下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
Run Code Online (Sandbox Code Playgroud)
如果没有产品,运动就不可能存在,所以sports_controller.rb我的拥有:
def new
@sport = Sport.new
@sport.product = Product.new
...
end
Run Code Online (Sandbox Code Playgroud)
我试图将产品的创建转移到运动模型,使用after_initialize:
after_initialize :create_product
def create_product
self.product = Product.new
end
Run Code Online (Sandbox Code Playgroud)
我很快就知道after_initialize只要模型被实例化(即来自一个find调用)就会被调用.所以这不是我想要的行为.
我应该如何建模所有人sport都有的要求product?
谢谢
bos*_*nou 62
如您所述,将逻辑放在控制器中可能是最佳答案,但您可以after_initialize通过执行以下操作来完成工作:
after_initialize :add_product
def add_product
self.product ||= Product.new
end
Run Code Online (Sandbox Code Playgroud)
这样,它只会在没有产品的情况下设置产品.它可能不值得开销和/或不如在控制器中具有逻辑那么清晰.
编辑:根据Ryan的回答,在性能方面,以下可能会更好:
after_initialize :add_product
def add_product
self.product ||= Product.new if self.new_record?
end
Run Code Online (Sandbox Code Playgroud)
Pau*_*eon 40
肯定after_initialize :add_product, if: :new_record?是这里最干净的方式.
将条件保留在add_product函数之外
Rya*_*yan 28
如果你这样做self.product ||= Product.new,每次你都会搜索产品,find因为它需要检查它是否为零.因此,它不会做任何急切的加载.为了仅在创建新记录时执行此操作,您可以在设置产品之前检查它是否是新记录.
after_initialize :add_product
def add_product
self.product ||= Product.new if self.new_record?
end
Run Code Online (Sandbox Code Playgroud)
我做了一些基本的基准测试,检查if self.new_record?似乎没有以任何明显的方式影响性能.
| 归档时间: |
|
| 查看次数: |
34411 次 |
| 最近记录: |