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

brg*_*brg 3 ruby-on-rails mongodb mongoid ruby-on-rails-4 mongoid4

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

主要模型

 class Sport
   include Mongoid::Document
   field :rules, type: Hash, default: {}
 end
Run Code Online (Sandbox Code Playgroud)

我想为:rule hash字段设置不同的默认哈希键的子类.例如,对于足球我想要规则:{:offside =>'',:penalty =>''}对于拳击我们可能有规则的哈希键:{:biting =>'not allowed'}.开源应用程序Errbit使用子类中的常量来设置默认哈希键,但我可以看到他们如何使用常量来填充哈希:https://github.com/errbit/errbit/blob/master/app/车型/ issue_trackers/github_issues_tracker.rb

 class Sport::Football < Sport
 end

 class Sport::Boxing < Sport
 end
Run Code Online (Sandbox Code Playgroud)

我确实覆盖了子类中的字段定义,如下所示,它在rails控制台中有效.当我做一个= Sport :: Football.new然后调用a.smtp返回默认设置.但问题是,当我去父类并执行b = Sport.newb.smtp时,我希望它能够列出子类的所有默认键,但它没有,因为我已经覆盖了子类中的哈希字段.

 class Sport::Football < Sport
    field :rules, type: Hash, default: {:offside => '', :penalty => ''}
 end
Run Code Online (Sandbox Code Playgroud)

有没有办法为子类设置默认哈希键而不覆盖字段定义.可以通过覆盖每个子类中哈希字段的setter和getter来做到这一点.

mu *_*ort 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
Run Code Online (Sandbox Code Playgroud)

当然,你不必default_rules私有化.您还需要default_rulesSport如果想要实例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
Run Code Online (Sandbox Code Playgroud)

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