我有一个带有哈希字段的 Mongoid 模型。这个 Mongoid 模型有使用单一集合继承的子类。现在我想为主模型的每个子类设置不同的默认哈希键。
主要模型
class Sport
include Mongoid::Document
field :rules, type: Hash, default: {}
end
我想为 :rule hash field 设置不同的默认哈希键的子类。例如,对于足球,我想要规则:{:offside => '', :penalty => ''}对于拳击,我们可能有规则的散列键:{:biting = >“不允许”。开源应用程序 Errbit 使用子类中的常量来设置默认哈希键,但我可以看到他们如何使用常量来填充哈希:https://github.com/errbit/errbit/blob/master/app/models/issue_trackers/github_issues_tracker.rb
class Sport::Football < Sport
end
class Sport::Boxing < Sport
end
我确实覆盖了子类中的字段定义,如下所示,它在 Rails 控制台中有效。当我执行 a = Sport::Football.new 然后调用 a.smtp 时返回默认设置。但这里的问题是,当我去父类做b = Sport.new 和b.smtp 时,我希望它能够列出所有默认值子类的键,但不是因为我已经覆盖了子类中的哈希字段。
class Sport::Football < Sport
field :rules, type: Hash, default: {:offside => '', :penalty => ''}
end
有没有办法在不覆盖字段定义的情况下为子类设置默认哈希键。可以通过覆盖每个子类中哈希字段的 setter 和 getter 来做到这一点。
最佳答案
:default
选项可以将 lambda 作为其值。在该 lambda 内部,self
将是您正在创建的新实例。这意味着您可以(间接)调用方法来提供默认值:
class Sport
include Mongoid::Document
field :rules, type: Hash, default: lambda { default_rules }
end
class Sport::Football < Sport
private
def default_rules
{ :offside => '', :penalty => '' }
end
end
class Sport::Boxing < Sport
private
def default_rules
{ :biting => 'not allowed except for ears' }
end
end
当然,您不必将 default_rules
设为私有(private)。如果您想直接实例化 Sport
,您还需要 Sport
中的 default_rules
。
您还可以使用回调之一手动设置规则:
class Sport
include Mongoid::Document
field :rules, type: Hash
after_initialize :set_default_rules, :if => :new_record? # Or one of the other callbacks.
end
和子类可以在它们的 set_default_rules
实现中说 self.rules = ...
。
关于ruby-on-rails - 为 mongoid 哈希字段设置默认哈希键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22783673/