【问题标题】:ActiveRecord: scheme for setting default attributes on new recordsActiveRecord:在新记录上设置默认属性的方案
【发布时间】:2013-04-24 16:15:58
【问题描述】:

我很好奇开发一个为新的 ActiveRecord 记录设置默认值的方案是否可行。根据herethis post on setting attributes 的一些答案,我想出了这样的事情:

class Taco < ActiveRecord::Base

  DEFAULT_ATTR = {spice_level: 4}

  before_save do |taco|
    if new_record?
      DEFAULT_ATTR.each do |k,v|
        taco[k] ||= v
      end 
    end 
  end 

end

对于偏执狂,该常量还可用于在迁移中设置默认值:

class CreateTacos  < ActiveRecord::Migration

  def defaults
    Taco::DEFAULT_ATTR
  end 

  def change
    add_column :tacos, :spice_level, :integer, :default => defaults[:spice_level]
  end 
end

如果这个方案作为回调内置到 ActiveRecord 中,可能有用(直到有人指出我忽略的一些明显方面!),比如 before_save(类似于“new_record_defaults”)。您可以重写该方法并返回符号 => 默认对的哈希值,甚至可能偏执的迁移代码也可以利用这一点。

我对 Rails 还很陌生,所以我准备被告知一个计划已经存在或者为什么这是一个愚蠢的想法,但欢迎反馈。 :)

更新:根据 Anton Grigoriev 的回答,我认为属性默认值 gem 是要走的路。对于后代,这里有一个额外的关注点,based on the author's original,用于访问创建的默认值:

module ActiveRecord
  module AttributesWithDefaultsAccessor
    extend ActiveSupport::Concern
    def all_defaults
      defaults = {}
      self.private_methods.each do |method|
        if method =~ /^__eval_attr_default_for_(.+)$/
          defaults[$1.to_sym] = self.send(method)
        end
      end
      defaults
    end
  end
  class Base
    include AttributesWithDefaultsAccessor
  end
end

【问题讨论】:

    标签: ruby-on-rails activerecord


    【解决方案1】:

    我更愿意将此逻辑保留在应用程序级别而不是数据库级别(通过迁移)。

    在应用层,这只是属性的覆盖

    class Taco < ActiveRecord::Base
      def spice_level
        read_attribute(:spice_level) || 4
      end
    end
    

    基本是,如果你设置了这个属性,比如5,那就是5。如果没有,那就是4。

    关于覆盖属性的参考: http://api.rubyonrails.org/classes/ActiveRecord/Base.html#label-Overwriting+default+accessors

    【讨论】:

    • 我也同意将应用程序逻辑保留在应用程序而不是数据库中,但我想利用模型中的默认值用于迁移作为辅助执行,因为迁移提供了它。有时人们喜欢在数据库中四处寻找,或者以其他方式处理 AR 领域之外的数据,虽然这种活动是否有效还有待商榷,但如果很容易获得第二层,恕我直言.
    • 这取决于此设置对您的重要性。但我更喜欢业务逻辑而不是业务领域。如果您想将其更改为 3 怎么办?又一次迁徙。如果有人想直接玩 db,他应该负责数据完整性,否则他正在破坏应用程序。顺便说一句,如果你真的没有太多的默认值来处理,那么使用 gem 就太过分了。避免以合理的成本添加宝石,否则您需要维护更多的东西、更多的不确定性和更多的开销。
    • 也不错。这也带来了这样一个事实,即从模型中移动要引用的默认值也会破坏迁移本身的版本控制,因为模型可能会发生变化,然后迁移现在意味着不同的东西。谢谢。
    【解决方案2】:

    你可以使用这个 gem https://github.com/bsm/attribute-defaults 来设置属性默认值

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-08
    • 1970-01-01
    • 2015-04-24
    • 2011-07-23
    • 1970-01-01
    • 2019-11-21
    相关资源
    最近更新 更多