Как получить данные из других таблиц с помощью Sequel

Я использую Sequel, и у меня есть следующие 2 модели в моем приложении Sinatra.

# foo.rb
require 'sequel'

module Notes
  module Models
    class Foo < Sequel::Model
      plugin :json_serializer, naked: true
      plugin :validation_helpers

      one_to_many :bars

      def validate
        super

        validates_presence [:foo_name], message: "can't be empty"
      end
    end
  end
end


# bar.rb
require 'sequel'

module Notes
  module Models
    class Bar < Sequel::Model
      plugin :json_serializer, naked: true
      plugin :validation_helpers

      many_to_one :foo

      def validate
        super

        validates_presence [:bar_name], message: "can't be empty"
      end
    end
  end
end

В таблице Bar есть внешний ключ foo_id.

У меня есть маршрут API, где вы можете получить все бары или только конкретный бар, если передается параметр, выглядит примерно так:

app.get '/api/bars' do
  require_session
  bar_name = params[:bar_name]
  bar_model = Models::Bar

  if bar_name.nil?
    bar_model.all.to_json
  else
    bar_model.where(Sequel.ilike(:bar_name, '%' + bar_name + '%'))
      .all
      .to_json
  end
end

Что я хотел бы сделать, но еще не понял, как я могу также получить как минимум foo_name из таблицы Foo в результате, полученном на основе foo_id из таблицы Bar?

Более того, что, если есть еще более длинная ассоциация, скажем, есть другой внешний ключ, например baz_id, в таблице Foo, связанной с таблицей Baz, и в этом же API я также хочу получить всю информацию из Foo и Baz-таблицы на основе ассоциации внешнего ключа в этих соответствующих таблицах.

Надеюсь, что это имеет смысл, и любая помощь приветствуется.


person Koes Bong    schedule 19.06.2015    source источник


Ответы (1)


Для этого вы можете использовать параметр :include метода to_json Sequel. Вы можете указать это в модели при установке параметров json_serializer, но вы также можете переопределить эти значения по умолчанию при вызове to_json для экземпляра.

Итак, на отдельном экземпляре Bar вы можете сделать:

Bar.first.to_json(include: {foo: {only: :foo_name}})

Если вы хотите сделать это для полного списка, как в вашем примере, вам нужно вызвать его в классе. Обратите внимание, что если вы вызовете его для массива, это не сработает, поэтому вы должны вызвать его для набора данных, прежде чем преобразовывать его в массив.

# all models 
Bar.to_json(include: {foo: {only: :foo_name}})

# a subset of models
Bar.where(Sequel.ilike(:bar_name, '%' + bar_name + '%'))
  .to_json(include: {foo: {only: :foo_name}})
person Nathan Ostgard    schedule 19.06.2015