Class: CachedSerializer::Base
- Inherits:
-
Object
- Object
- CachedSerializer::Base
- Defined in:
- lib/cached_serializer/base.rb
Instance Attribute Summary collapse
-
#subject ⇒ Object
Returns the value of attribute subject.
Class Method Summary collapse
-
.columns(*column_names) ⇒ Object
Example (in a UserSerializer):.
-
.computed(attr_name, columns: [], recompute_if: nil, expires_in: nil, &recompute) ⇒ Object
Example (in a UserSerializer):.
-
.constant(*attr_names, &recompute) ⇒ Object
Example (in a UserSerializer):.
- .serializers ⇒ Object
-
.subject_class(subject_class = nil) ⇒ Object
Examples:.
-
.volatile(*attr_names, &recompute) ⇒ Object
Example (in a UserSerializer):.
Instance Method Summary collapse
- #as_json ⇒ Object
-
#initialize(subject) ⇒ Base
constructor
A new instance of Base.
- #to_h ⇒ Object
- #to_json ⇒ Object
Constructor Details
#initialize(subject) ⇒ Base
Returns a new instance of Base.
176 177 178 179 180 181 182 |
# File 'lib/cached_serializer/base.rb', line 176 def initialize(subject) unless subject.is_a?(self.class.subject_class) raise CachedSerializer::Error, "Subject is not a #{self.class.subject_class} (use `subject_class #{subject.class}` in your serializer to serialize #{subject.class} records)" end self.subject = subject end |
Instance Attribute Details
#subject ⇒ Object
Returns the value of attribute subject.
9 10 11 |
# File 'lib/cached_serializer/base.rb', line 9 def subject @subject end |
Class Method Details
.columns(*column_names) ⇒ Object
Example (in a UserSerializer):
columns :email, :phone
This will call ‘some_user.email` for the `:email` attribute, and `some_user.phone` for the `:phone` attribute. It will cache the value for each, until the attribute changes on the record.
60 61 62 63 64 65 |
# File 'lib/cached_serializer/base.rb', line 60 def columns(*column_names) column_names.each do |column_name| serializers << AttrSerializer.new(column_name) add_column_changed_cache_invalidator_callback(column_name, column_name) end end |
.computed(attr_name, columns: [], recompute_if: nil, expires_in: nil, &recompute) ⇒ Object
Example (in a UserSerializer):
computed :name, columns: [:first_name, :last_name] do |user|
"#{user.first_name} #{user.last_name}"
end
This will use the result of the block as the value for the ‘:name` attribute. It will cache the result until either `:first_name` or `:last_name` changes on the user record.
computed :active, recompute_if: ->(u) { u.last_logged_in_at > 1.week.ago } do |user|
user.purchases.where(created_at: 1.week.ago..Time.zone.now).present?
end
This will use the result of the block as the value for the ‘:active` attribute. It will cache the result until the `recompute_if` proc/lambda returns `true`.
computed :purchase_count, expires_in: 1.day do |user|
user.purchases.count
end
This will use the result of the block as the value for the ‘:purchase_count` attribute. It will cache the result for one day after the last time the `:purchase_count` attribute was recomputed.
computed :silly, columns: [:foo, :bar], recompute_if: ->(u) { u.silly? }, expires_in: 10.seconds do |user|
rand(100)
end
This will use the result of the block as the value for the ‘:silly` attribute. It will cache the result until `:foo` changes on the user, `:bar` changes on the user, `u.silly?` at the time of serialization, or it has been more than 10 seconds since the last time the `:silly` attribute was recomputed.
147 148 149 150 151 152 153 154 155 |
# File 'lib/cached_serializer/base.rb', line 147 def computed(attr_name, columns: [], recompute_if: nil, expires_in: nil, &recompute) if (columns.empty? && !recompute_if && !expires_in) raise ArgumentError, "Must provide :columns, :recompute_if, or :expires_in to a computed attribute setter" end serializers << AttrSerializer.new(attr_name, recompute_if, expires_in, &recompute) columns.each do |column_name| add_column_changed_cache_invalidator_callback(attr_name, column_name) end end |
.constant(*attr_names, &recompute) ⇒ Object
Example (in a UserSerializer):
constant :email, :phone
This will call ‘some_user.email` for the `:email` attribute, and `some_user.phone` for the `:phone` attribute. It will cache the value for each FOREVER, and never recompute it.
constant :name do |user|
"#{user.first_name} #{user.last_name}"
end
This will use the result of the block as the value for the ‘:name` attribute. It will cache the value FOREVER, and never recompute it.
82 83 84 85 86 |
# File 'lib/cached_serializer/base.rb', line 82 def constant(*attr_names, &recompute) attr_names.each do |attr_name| serializers << AttrSerializer.new(attr_name, &recompute) end end |
.serializers ⇒ Object
48 49 50 |
# File 'lib/cached_serializer/base.rb', line 48 def serializers @serializers ||= AttrSerializerCollection.new end |
.subject_class(subject_class = nil) ⇒ Object
Examples:
module Admin
class UserSerializer < CachedSerializer::Base
subject_class User
# ...
end
end
class AuthorSerializer < CachedSerializer::Base
subject_class User
# ...
end
If you want to serialize a model and name the serializer something other than “‘ModelName` + `Serializer`” (e.g., `AuthorSerializer` to serialize `User` records), or to put it in a module (e.g., `Admin::UserSerializer` to differentiate it from an existing `UserSerializer`) use `::subject_class` to specify the class of the model you will be serializing.
34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/cached_serializer/base.rb', line 34 def subject_class(subject_class = nil) return @subject_class if @subject_class && !subject_class subject_class_name = case subject_class.class.to_s when 'Class' then subject_class.to_s when 'String' then subject_class.classify else self.to_s.gsub(/[Ss]erializer\z/, '') end @subject_class = subject_class_name.constantize rescue NameError raise CachedSerializer::Error, "Cannot find a #{subject_class_name} model class for serialization (use the `subject_class TheModelName` in #{self.to_s} to specify which model to serialize)" end |
.volatile(*attr_names, &recompute) ⇒ Object
Example (in a UserSerializer):
volatile :email, :phone
This will call ‘some_user.email` for the `:email` attribute, and `some_user.phone` for the `:phone` attribute. It will ALWAYS recompute the values, EVERY time it serializes a user.
volatile :name do |user|
"#{user.first_name} #{user.last_name}"
end
This will use the result of the block as the value for the ‘:name` attribute. It will ALWAYS recompute the value, EVERY time it serializes a user.
104 105 106 107 108 109 |
# File 'lib/cached_serializer/base.rb', line 104 def volatile(*attr_names, &recompute) attr_names.each do |attr_name| always_recompute = proc { |_subj| true } serializers << AttrSerializer.new(attr_name, always_recompute, &recompute) end end |
Instance Method Details
#as_json ⇒ Object
188 189 190 |
# File 'lib/cached_serializer/base.rb', line 188 def as_json to_h end |
#to_h ⇒ Object
184 185 186 |
# File 'lib/cached_serializer/base.rb', line 184 def to_h self.class.serializers.serialize_for(subject) end |
#to_json ⇒ Object
192 193 194 |
# File 'lib/cached_serializer/base.rb', line 192 def to_json JSON.generate(as_json) end |