Получение ошибки при попытке кодирования сообщения с помощью Protobuf

#ruby-on-rails #protocol-buffers

Вопрос:

Сгенерированный Протобуф:

 # source: event.proto

require 'google/protobuf'

Google::Protobuf::DescriptorPool.generated_pool.build do
  add_file("event.proto", :syntax => :proto3) do
    add_message "myapp.Event" do
      optional :name, :string, 1
      optional :entity, :enum, 2, "myapp.Event.Entity"
      oneof :event_data do
        optional :first_event_data, :message, 3, "myapp.Event.FirstEventData"
        optional :second_event_data, :message, 4, "myapp.Event.SecondEventData"
      end
    end
    add_message "myapp.Event.FirstEventData" do
      optional :id, :string, 1
      optional :to, :string, 2
      optional :from, :string, 3
    end
    add_message "myapp.Event.SecondEventData" do
      optional :metadata_url, :string, 1
    end
    add_enum "myapp.Event.Entity" do
      value :FIRST, 0
      value :SECOND, 1
    end
  end
end

module Myapp
  Event = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("myapp.Event").msgclass
  Event::FirstEventData = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("myapp.Event.FirstEventData").msgclass
  Event::SecondEventData = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("myapp.Event.SecondEventData").msgclass
  Event::Entity = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("myapp.Event.Entity").enummodule
end
 

Теперь в консоли, когда я делаю

 message = Myapp::Event.new(
        entity: :SECOND, 
        name: "started",
        event_data: {
          second_event_data: 
            Myapp::Event::SecondEventData.new(
              metadata_url: "local-dev-url",
            )
        }
      )
 

Я получаю эту ошибку:

 Traceback (most recent call last):
        3: from (irb):178
        2: from (irb):178:in `new'
        1: from (irb):178:in `initialize'
ArgumentError (Unknown field name 'event_data' in initialization map entry.)
 

Я пробовал разные комбинации, и каждый раз, когда возникают разные ошибки, я думаю message , что неправильно упорядочиваю свои.

Любая помощь будет очень признательна. Спасибо

Ответ №1:

Ну, после долгих исследований, очевидно, я не могу сделать все это сразу. Мне нужно создать 2 или 3 отдельных объекта: т. е.

 message = Myapp::Event.new(
        entity: :SECOND, 
        name: "started")
 

И тогда я смогу сделать это:

 message.second_event_data = Myapp::Event::SecondEventData.new(
              metadata_url: "local-dev-url",
            )
 

Затем, когда я закодирую его, second_event_data Уилл сядет под event_data