In Rails 5, is it possible to use the new attributes API with a field exposed via store_accessor
on a jsonb
column?
For example, I have:
class Item < ApplicationRecord
# ...
store_accessor :metadata, :publication_date
attribute :publication_date, :datetime
end
Then I'd like to call i = Item.new(publication_date: '2012-10-24')
, and have metadata
be a hash like: { 'publication_date' => #<DateTimeInstance> }
.
However, the attribute
call doesn't seem to be doing any coercion.
Hopefully I am missing something--it seems like being able to use these two features in conjunction would be very useful when working with jsonb
columns. (Speaking of which, why doesn't the attributes API expose a generic array: true
option? That would also be very useful for this case.)
答案 0 :(得分:1)
在进一步挖掘之后,我发现属性API(因为它当前存在于ActiveRecord中)不适合处理jsonb
数据 - attributes
哈希中会有重复的信息等等。
我认为如果ActiveRecord为jsonb
字段提供了类型转换/强制效果会很好。我看到有一个项目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