module ViewModel::ActiveRecord::Controller

Controller for accessing an ViewModel::ActiveRecord Provides for the following routes: POST /models create – create or update one or more models GET /models index GET /models/:id show DELETE /models/:id destroy

Constants

MIGRATION_VERSION_HEADER

Public Instance Methods

create(serialize_context: new_serialize_context, deserialize_context: new_deserialize_context) { |view| ... } click to toggle source
# File lib/view_model/active_record/controller.rb, line 44
def create(serialize_context: new_serialize_context, deserialize_context: new_deserialize_context)
  update_hash, refs = parse_viewmodel_updates

  view = nil
  pre_rendered = viewmodel_class.transaction do
    view = viewmodel_class.deserialize_from_view(update_hash, references: refs, deserialize_context: deserialize_context)
    ViewModel.preload_for_serialization(view)
    view = yield(view) if block_given?
    prerender_viewmodel(view, serialize_context: serialize_context)
  end
  render_json_string(pre_rendered)
  view
end
destroy(serialize_context: new_serialize_context, deserialize_context: new_deserialize_context) click to toggle source
# File lib/view_model/active_record/controller.rb, line 58
def destroy(serialize_context: new_serialize_context, deserialize_context: new_deserialize_context)
  viewmodel_class.transaction do
    view = viewmodel_class.find(viewmodel_id, eager_include: false)
    view.destroy!(deserialize_context: deserialize_context)
  end
  render_viewmodel(nil)
end
index(scope: nil, viewmodel_class: self.viewmodel_class, serialize_context: new_serialize_context(viewmodel_class: viewmodel_class)) { |views| ... } click to toggle source
# File lib/view_model/active_record/controller.rb, line 33
def index(scope: nil, viewmodel_class: self.viewmodel_class, serialize_context: new_serialize_context(viewmodel_class: viewmodel_class))
  views = nil
  pre_rendered = viewmodel_class.transaction do
    views = viewmodel_class.load(scope: scope)
    views = yield(views) if block_given?
    prerender_viewmodel(views, serialize_context: serialize_context)
  end
  render_json_string(pre_rendered)
  views
end
parse_viewmodel_updates() click to toggle source
Calls superclass method
# File lib/view_model/active_record/controller.rb, line 70
def parse_viewmodel_updates
  super.tap do |update_hash, refs|
    if migration_versions.present?
      migrator = ViewModel::UpMigrator.new(migration_versions)
      migrator.migrate!({ 'data' => update_hash, 'references' => refs })
    end
  end
end
prerender_viewmodel(...) { |jbuilder| ... } click to toggle source
# File lib/view_model/active_record/controller.rb, line 79
def prerender_viewmodel(...)
  super do |jbuilder|
    yield(jbuilder) if block_given?

    # migrate the resulting structure before it's serialized to a json string
    if migration_versions.present?
      tree = jbuilder.attributes!
      migrator = ViewModel::DownMigrator.new(migration_versions)
      migrator.migrate!(tree)
    end
  end
end
show(scope: nil, viewmodel_class: self.viewmodel_class, serialize_context: new_serialize_context(viewmodel_class: viewmodel_class)) { |view| ... } click to toggle source
# File lib/view_model/active_record/controller.rb, line 22
def show(scope: nil, viewmodel_class: self.viewmodel_class, serialize_context: new_serialize_context(viewmodel_class: viewmodel_class))
  view = nil
  pre_rendered = viewmodel_class.transaction do
    view = viewmodel_class.find(viewmodel_id, scope: scope)
    view = yield(view) if block_given?
    prerender_viewmodel(view, serialize_context: serialize_context)
  end
  render_json_string(pre_rendered)
  view
end

Private Instance Methods

migrated_deep_schema_version() click to toggle source
# File lib/view_model/active_record/controller.rb, line 137
def migrated_deep_schema_version
  ViewModel::Migrator.migrated_deep_schema_version(viewmodel_class, migration_versions, include_referenced: true)
end
migration_versions() click to toggle source
# File lib/view_model/active_record/controller.rb, line 98
def migration_versions
  @migration_versions ||=
    begin
      version_spec =
        if params.include?(:versions)
          params[:versions]
        elsif request.headers.include?(MIGRATION_VERSION_HEADER)
          begin
            JSON.parse(request.headers[MIGRATION_VERSION_HEADER])
          rescue JSON::ParserError
            raise ViewModel::Error.new(status: 400, detail: "Invalid JSON in #{MIGRATION_VERSION_HEADER}")
          end
        else
          {}
        end

      versions =
        IknowParams::Parser.parse_value(
          version_spec,
          with: IknowParams::Serializer::HashOf.new(
            IknowParams::Serializer::String, IknowParams::Serializer::Integer))

      migration_versions = {}

      versions.each do |view_name, required_version|
        viewmodel_class = ViewModel::Registry.for_view_name(view_name)

        if viewmodel_class.schema_version != required_version
          migration_versions[viewmodel_class] = required_version
        end
      rescue ViewModel::DeserializationError::UnknownView
        # Ignore requests to migrate types that no longer exist
        next
      end

      migration_versions.freeze
    end
end
viewmodel_id() click to toggle source
# File lib/view_model/active_record/controller.rb, line 94
def viewmodel_id
  parse_param(:id)
end