可以将“attribute”与“store_accessor”一起使用

Jac*_*own 5 ruby-on-rails ruby-on-rails-5

store_accessor在 Rails 5 中,是否可以将新的属性 API 与通过列公开的字段一起使用jsonb

例如,我有:

class Item < ApplicationRecord
  # ...
  store_accessor :metadata, :publication_date
  attribute :publication_date, :datetime
end
Run Code Online (Sandbox Code Playgroud)

然后我想打电话给i = Item.new(publication_date: '2012-10-24'),并得到metadata一个像这样的哈希值:{ 'publication_date' => #<DateTimeInstance> }

不过,这个attribute电话似乎并没有任何强制作用。

希望我遗漏了一些东西——在使用列时,能够结合使用这两个功能似乎非常有用jsonb。(说到这里,为什么属性 API 不公开通用array: true选项?这对于这种情况也非常有用。)

Jac*_*own 1

深入研究后,我发现 Attributes API(当前存在于 ActiveRecord 中)并不真正适合处理jsonb数据 — 哈希中可能存在重复信息attributes等。

jsonb我确实认为如果 ActiveRecord 为字段提供类型转换/强制转换,那就太好了。我看到有一个项目jsonb_accessor,但看起来有点重量级。它似乎也是为 Rails 4 设计的(我还没有检查它是否支持 Rails 5)。

我猜想 Rails 可能正在使用类似的东西,因为这些ActiveRecord::Type值实际上是在 ActiveModel 中定义的。

现在我正在使用以下内容。我从来没有真正喜欢过 Hashie,但它相对轻量且易于使用:

class Item < ApplicationRecord
  class Metadata < Hashie::Dash

    include Hashie::Extensions::Dash::Coercion
    include Hashie::Extensions::Dash::IndifferentAccess

    property :publication_date, coerce: Time

    def self.dump(obj); obj.as_json; end
    def self.load(obj); new(obj); end

  end

  serialize :metadata, Metadata
  store_accessor :metadata, :publication_date
end
Run Code Online (Sandbox Code Playgroud)