【问题标题】:calling child class method in parent class method在父类方法中调用子类方法
【发布时间】:2015-01-23 21:04:09
【问题描述】:

我有 rails 4 应用程序和这个模型

class Product < AR::Base

  default_scope -> { where(product_type: self.to_s) }
  after_initialize { self.product_type = self.class.to_s }

end

还有很多类似的

class Orange < Product #Apple, Carrot, ...

end

如果我在控制台&gt;&gt; Orange.new 中调用,回调after_initialize 的工作方式与预期一样:它将实例属性product_type 设置为Orange,因此self.class 被确定为Orange 类,就像我需要的那样

但是

如果我调用&gt;&gt; Orange.alldefault_scope 内部的方法self.to_s 将应用于Product class=(

所以,问题来了:如果我不想在 default_scope 的父类 (Product) 中使用 Orange 类名,以防我在 @ 中编写任何方法987654337@ 类(因为有很多像Orange 这样的子类,我想让所有东西都干)。

等等,如果我有Apple 类,如果我调用&gt;&gt; Apple.all(某种多态关联),它的名称必须用于过滤所有Productdefault_scope(某种多态关联)

谢谢。

【问题讨论】:

  • 不是您问题的答案,但您知道您是否使用STI ActiveRecord 如果您在子类上调用查询方法,它会为您做到这一点吗? Product.all.to_sql =&gt; "SELECT * FROM products"Orange.all.to_sql =&gt; "SELECT * FROM products WHERE type = 'Orange'"
  • @NathanWallace,结果是一样的:SELECT products.* FROM products WHERE products.product_type = 'Product'
  • 如果子类(橙色)尚未加载,可能会发生这种情况——这是 require_dependency 有用的少数情况之一
  • @FrederickCheung,那么递归依赖(Product-&gt;Orange-&gt;Product...)不会发生吗?
  • 没有。 Orange 不会导致 Product 被第二次加载,因为它已经被加载了。

标签: ruby-on-rails ruby polymorphism polymorphic-associations sti


【解决方案1】:

这里只使用 STI:

class Product < ActiveRecord::Base
  self.inheritance_column = :product_type
end

class Orange < Product
end

# then...

> Orange.all
Orange Load (0.1ms)  SELECT "products".* FROM "products" WHERE "products"."product_type" IN ('Orange')

即。不要使用default_scopeafter_initialize,因为一旦你从另一个模型继承,Rails 已经涵盖了你,Rails 会假设你正在使用 STI,它会在查询中添加正确的内容。

【讨论】:

  • 这就是解决我当前问题的方法,所以,谢谢 - 接受,但更通用的问题仍然是实际的 -> 我如何编写父类级别的方法(不是例如,而是 def self. ...)使用子类级别方法(即父def self.current_sti_class_name方法中的子类名)
  • 在此评论中执行您所要求的操作并没有什么复杂的,但是使用 Rails 中的 after_initialize 方法您不会到达那里,因为它在 self 上关闭,所以 @ 987654328@ 将始终是执行 after_initialize 时的任何内容 - 即。它永远是父类。如果您只使用 ruby​​,那么您想要的会自动发生:class Foo; def self.blah; puts self.to_s; end; end; class Bar &lt; Foo; end; Bar.blah #=&gt; 'Bar'
猜你喜欢
  • 2016-02-14
  • 2017-11-09
  • 2011-09-04
  • 2012-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-26
相关资源
最近更新 更多