为mongoid哈希字段设置默认哈希键

时间:2014-04-01 10:49:57

标签: ruby-on-rails mongodb ruby-on-rails-4 mongoid mongoid4

我有一个带有哈希字段的Mongoid模型。此Mongoid模型具有使用单个集合继承的子类。现在我想为主模型的每个子类设置不同的默认哈希键

主要模型

 class Sport
   include Mongoid::Document
   field :rules, type: Hash, default: {}
 end

我想为:规则哈希字段设置不同的默认哈希键的子类。例如,对于足球我想要规则:{:offside => '',:惩罚=> ''} 对于Boxing,我们可能有规则的哈希键:{: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来做到这一点。

1 个答案:

答案 0 :(得分:5)

: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。如果您想直接实例化default_rules,您还需要Sport中的Sport

您也可以使用其中一个回调来手动设置规则:

class Sport
  include Mongoid::Document
  field :rules, type: Hash
  after_initialize :set_default_rules, :if => :new_record? # Or one of the other callbacks.
end

和子类可以在self.rules = ...实现中说set_default_rules