Synopsys
This is a support library for openEHR on Rails implementation and still working exeperimental codes.
Requirements
- Current version supports Rails 7.0+ and Rails 8.x
- Requires Ruby 3.0 or later (tested with Ruby 3.4)
- Developed with CRuby 3.4 on Linux
- Previous versions supported older Ruby/Rails versions (see git history)
Usage
Generate a complete Rails resource (model, migration, controller, views, routes, i18n locale, request spec) from an openEHR Operational Template (.opt):
# one-time setup: template registry model + migration + initializer
bin/rails generate openehr:install
bin/rails db:migrate
# scaffold from an OPT file
bin/rails generate openehr:scaffold path/to/your_template.opt
bin/rails db:migrate
bin/rails db:seed # registers the template in the openehr_templates table
The generated model keeps typed columns for Rails forms and queries,
and persists every record as a canonical openEHR RM Composition —
first as a typed node graph in openehr_rm_* tables (if the
install migrations were run), and also as a JSON document in the
rm_composition column for backward compatibility and export.
The FIELD_MAP constant on the model links each column to its openEHR
RM path and data value type. Model.find_by_path(rm_path, value)
resolves RM paths to columns (OpenehrRails::AqlQueryable); if a
path is not in FIELD_MAP, the search falls back to the RM graph (when
available), allowing arbitrary archetype elements to be queried
(OpenehrRails::Rm layer).
Options:
--namespace=ehrnamespaces controller, views and routes.--fhiralso writes HL7 FHIR R5 StructureDefinition profiles (one per OPT entry) toapp/fhir/profiles/. They can also be generated standalone withbin/rails generate openehr:fhir_profile <opt>.
Template admin UI
openehr:install mounts an admin engine at /openehr. It lists the
registered templates and accepts OPT files via drag & drop upload;
the Generate UI button runs the scaffold generator inside the
running app (generates files, migrates, reloads routes), so the new
resource is usable immediately without restarting the server.
Runtime scaffolding writes files into the application, so it is enabled in the development environment only. Override with:
# config/initializers/openehr.rb
OpenehrRails.enable_runtime_scaffolding = true # or false
Authentication
Everything the engine serves — the template admin UI, the AQL console,
the patient timeline, the openEHR REST API (/openehr/v1) and the FHIR
facade (/openehr/fhir) — handles clinical data, so outside the
development and test environments the engine is closed by
default: every request gets 403 Forbidden until you configure an
authentication hook.
The hook runs as a before_action inside the engine controller handling
the request (instance_exec'd, so it can use request, render,
redirect_to, and any helper your app mixes into ActionController::Base).
Deny by rendering or redirecting — a hook that raises would be caught
and reported as a misleading error by some engine controllers'
rescue_from StandardError.
# config/initializers/openehr.rb
# Devise:
OpenehrRails.authenticate_with = -> { authenticate_user! }
# Bearer token:
OpenehrRails.authenticate_with = lambda do
authenticate_or_request_with_http_token do |token, |
ActiveSupport::SecurityUtils.secure_compare(
token, Rails.application.credentials.openehr_api_token.to_s
)
end
end
To use a different mechanism per surface, branch on openehr_access_scope
(:admin — template UI / AQL console / timeline, :rest_api — /v1,
:fhir — the FHIR facade):
OpenehrRails.authenticate_with = lambda do
case openehr_access_scope
when :admin then authenticate_user!
else authenticate_or_request_with_http_token { |t, _| valid_api_token?(t) }
end
end
To intentionally run without authentication (e.g. behind a reverse proxy that already authenticates, or a network-isolated internal app):
OpenehrRails.allow_unauthenticated_access = true
Note: the JSON API controllers (/v1, /fhir) skip CSRF protection, so
prefer token authentication over session cookies for those.
HL7 FHIR R5 facade
The engine also serves a FHIR R5 API under <mount>/fhir
(/openehr/fhir by default), backed by the scaffolded models:
GET /openehr/fhir/metadata— CapabilityStatement listing every registered archetype profileGET /openehr/fhir/StructureDefinition/:id— generated profilesGET /openehr/fhir/Observation?code=<archetype_id>&subject=<ref>— searchset BundleGET /openehr/fhir/Observation/:id— readPOST /openehr/fhir/Observation— create; the FHIR resource is converted through the model's FIELD_MAP and stored canonically as an openEHR RM Composition (rm_compositioncolumn). Errors are returned as OperationOutcome.
Mapping is derived automatically from openEHR RM types
(OBSERVATION→Observation, DV_QUANTITY→Quantity,
DV_CODED_TEXT→CodeableConcept, ...; see
OpenehrRails::Fhir::TypeMap).
Starting a new app from scratch
templates/openehr_template.rb is a
Rails application template that wires up a brand new app with
openehr-rails (openehr:install, migrated) in one command:
rails new myehr -m https://raw.githubusercontent.com/skoba/openehr-rails/master/templates/openehr_template.rb
Set OPENEHR_SAMPLES=1 to also scaffold the 3 sample templates used by
this repo's own demo (BMI, problem list, blood pressure), fetched over
HTTP via OpenehrRails::Opt::RemoteFetcher. See the file's header
comment for all options.
script/build_starter.sh wraps the same
template to produce a standalone repo (with its own README and CI
workflow) suitable for pushing to GitHub as a
template repository.
デモ環境(OPT → Rails アプリ)
script/build_demo.sh は、この gem を使って OPT から Rails アプリを生成し
動かすデモをゼロから再現構築します(demo/ を新規作成 → BMI / 問題リストの
2 テンプレートを scaffold → サンプルデータ投入まで一括実行)。
bash script/build_demo.sh
cd demo && bin/rails server # http://localhost:3000
手順の詳細・生成物の解説・管理 UI・FHIR R5 facade の確認方法は
日本語マニュアル doc/DEMO_ja.md を参照してください。
生成される demo/ は再現可能なため git では追跡しません。
License
This product is under Apache 2.0 license
Copyright 2012-2026 Shinji Kobayashi, openEHR.jp
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.