sql >> Base de Datos >  >> RDS >> PostgreSQL

¿Puedo escribir funciones de PostgreSQL en Ruby on Rails?

Esta parte de tu pregunta:

Sé que podemos crearlo manualmente en PostgreSQL, pero la "magia" con Active Record es que la base de datos se puede recrear con todos los modelos.

me dice que realmente está buscando una forma de integrar las funciones de PostgreSQL con el proceso normal de migración de Rails y las tareas de Rake como db:schema:load .

Agregar y quitar funciones en las migraciones es fácil:

def up
  connection.execute(%q(
    create or replace function ...
  ))
end

def down
  connection.execute(%q(
    drop function ...
  ))
end

Necesitas usar up separado y down métodos en lugar de un único change método porque ActiveRecord no tendrá idea de cómo aplicar y mucho menos revertir la creación de una función. Y usas connection.execute para alimentar la definición de función sin procesar a PostgreSQL. También puedes hacer esto con un reversible dentro de change :

def change
  reversible do |dir|
    dir.up do
      connection.execute(%q(
        create or replace function ...
      ))
    end
    dir.down do
      connection.execute(%q(
        drop function ...
      ))
    end
  end
end

pero lo encuentro más ruidoso que up y down .

Sin embargo, schema.rb y las tareas habituales de Rake que funcionan con schema.rb (como db:schema:load y db:schema:dump ) no sabrá qué hacer con las funciones de PostgreSQL y otras cosas que ActiveRecord no comprende. Sin embargo, hay una forma de evitar esto, puede elegir usar un structure.sql archivo en lugar de schema.rb configurando:

config.active_record.schema_format = :sql

en su config/application.rb expediente. Después de eso, db:migrate escribirá un db/structure.sql (que es solo un volcado SQL sin formato de su base de datos PostgreSQL sin sus datos) en lugar de db/schema.rb . También usará diferentes tareas Rake para trabajar con structure.sql :

  • db:structure:dump en lugar de db:schema:dump
  • db:structure:load en lugar de db:schema:load

Todo lo demás debería funcionar igual.

Este enfoque también le permite usar otras cosas en su base de datos que ActiveRecord no comprenderá:restricciones CHECK, disparadores, valores predeterminados de columna no simples, ...