Examples
Sub messages
message Post {
uint64 id = 1;
string title = 2;
User author = 3;
}
message User {
uint64 id = 1;
string name = 2;
}
class Book < ActiveRecord::Base
belongs_to :author, class_name: 'User'
end
class User < ActiveRecord::Base
end
class BookPbSerializer < Pb::Serializer::Base
message ExamplesPb::Book
attribute :id
attribute :title
attribute :author, serializer: UserPbSerializer
end
class UserPbSerializer < Pb::Serializer::Base
message ExamplesPb::User
attribute :id
attribute :name
end
Enum
message Conversation {
uint64 id = 1;
Status status = 3;
enum Status {
STATUS_UNSPECIFIED = 0;
ARCHIVED = 1;
ACTIVE = 2;
}
}
class Conversation < ApplicationRecord
enum status: { active: 0, archived: 1 }, _prefix: true
end
class ConversationPbSerializer < Pb::Serializer::Base
message ExamplesPb::Conversation
attribute :status
def status
object.status.upcase.to_sym
end
end
Oneof
message Entry {
oneof entry {
Message message = 1;
Comment comment = 2;
}
}
message Message {
// ...
}
message Comment {
// ...
}
class Entry < ApplicationRecord
delegated_type :entryable, types: %w[Message Comment]
end
class Message < ApplicationRecord
end
class < ApplicationRecord
end
class EntryPbSerializer < Pb::Serializer::Base
message ExamplesPb::Entry
oneof :entry do
attribute :message, if: -> { object.message? }, serializer: MessagePbSerializer
attribute :comment, if: -> { object. }, serializer:
end
end
class MessagePbSerializer < Pb::Serializer::Base
message ExamplesPb::Message
end
class < Pb::Serializer::Base
message ExamplesPb::
end
Serializable model
message User {
uint64 id = 1;
string first_name = 2;
string last_name = 3;
}
class User < ActiveRecord::Base
include Pb::Serializable
message ExamplesPb::User
attribute :id
attribute :first_name
attribute :last_name
end
User.find(123).to_pb
With FieldMask and ComputedModel
message User {
uint64 id = 1;
string first_name = 2;
string last_name = 3;
string full_name = 4;
}
class RawUser < ActiveRecord::Base
self.table_name = 'users'
end
class User
include ComputedModel::Model
def initialize(raw_user)
@raw_user = user
end
def self.batch_get(ids, with:)
bulk_load_and_compute([*Array(with), :id], ids: ids)
end
define_primary_loader :raw_user do |subfields, ids:, **|
RawUser.where(id: ids).select(subfields).map { new(_1) }
end
delegate_dependency :id, :first_name, :last_name,
to: :raw_user, include_subfields: true
dependency :first_name, :last_name
computed def full_name
[first_name, last_name].compact.join(' ')
end
end
class UserPbSerializer < Pb::Serializer::Base
message ExamplesPb::User
attribute :id
attribute :first_name
attribute :last_name
attribute :full_name
end
mask = Pb::Serializer.parse_field_mask(req.read_mask)
user = User.batch_get([123], with: mask)[0]
UserPbSerializer.new(user).to_pb(with: mask)