メモリ内のオブジェクトをデータベースに保存し、そのオブジェクトを Dalli でキャッシュしようとすると、奇妙な動作が発生します。
class Infraction << ActiveRecord::Base
has_many :infraction_locations
has_many :tracked_points, through: :infraction_locations
end
class TrackedPoint << ActiveRecord::Base
has_many :infraction_locations
has_many :infractions, through: :infraction_locations
end
class InfractionLocation << ActiveRecord::Base
belongs_to :infraction
belongs_to :tracked_point
belongs_to :rule
end
これは機能します:
i = Infraction.create
i.tracked_points << TrackedPoint.create(location_id: 1)
i.save
Rails.cache.write "my_key", i
これも機能します:
i = Infraction.new
i.tracked_points << TrackedPoint.create(location_id: 1)
i.save
Rails.cache.write "my_key", i
オブジェクト (2 番目のケースでは のみTrackedPoint
) は、create の呼び出しによって暗黙的にデータベースに保存されることに注意してください。
また、リロードi
するとオブジェクトをキャッシュに書き込むことができることもわかりました。したがって、これは機能します:
i = Infraction.new
i.tracked_points << TrackedPoint.new(location_id: 1)
i.save
i.reload
Rails.cache.write "my_key", i
これは失敗します:
i = Infraction.new
i.tracked_points << TrackedPoint.new(location_id: 1)
i.save
Rails.cache.write "my_key", i
ただし、奇妙な複製を行うと、失敗した例を機能させることができます。
i = Infraction.new
i.tracked_points << TrackedPoint.new(location_id: 1)
i.save
copy = i.dup
copy.tracked_points = i.tracked_points.to_a
Rails.cache.write "my_key", copy
私の失敗した例ではi
、次のように、データベースに保存する前に違反 ( )をキャッシュできます。
i = Infraction.new
i.tracked_points << TrackedPoint.new(location_id: 1)
Rails.cache.write "what", i
Dave のアイデアに従って、 for のbuild
代わりにを追加するだけでなく、toを追加しようとしましたが、どちらも機能しませんでした。<<
TrackedPoint
accepts_nested_attributes_for :tracked_points
Infraction
ログにマーシャリング/シリアライザー エラーが記録されています。
You are trying to cache a Ruby object which cannot be serialized to memcached.
Rails 3.2.13 と Dalli 2.7.0 を実行しています
編集