PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Puis-je écrire des fonctions PostgreSQL sur Ruby on Rails ?

Cette partie de votre question :

Je sais que nous pouvons le créer manuellement dans PostgreSQL, mais la "magie" avec Active Record est que la base de données peut être recréée avec tous les modèles.

me dit que vous cherchez vraiment un moyen d'intégrer les fonctions PostgreSQL avec le processus de migration Rails normal et les tâches Rake telles que db:schema:load .

L'ajout et la suppression de fonctions dans les migrations sont faciles :

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

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

Vous devez utiliser un up séparé et down méthodes au lieu d'un seul change car ActiveRecord n'aura aucune idée de comment appliquer et encore moins inverser la création d'une fonction. Et vous utilisez connection.execute pour envoyer la définition de fonction brute à PostgreSQL. Vous pouvez également le faire avec un reversible à l'intérieur 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

mais je trouve ça plus bruyant que up et down .

Cependant, schema.rb et les tâches Rake habituelles qui fonctionnent avec schema.rb (comme db:schema:load et db:schema:dump ) ne saura pas quoi faire avec les fonctions PostgreSQL et d'autres choses qu'ActiveRecord ne comprend pas. Il existe cependant un moyen de contourner cela, vous pouvez choisir d'utiliser un structure.sql fichier au lieu de schema.rb en définissant :

config.active_record.schema_format = :sql

dans votre config/application.rb dossier. Après cela, db:migrate écrira un db/structure.sql fichier (qui est juste un vidage SQL brut de votre base de données PostgreSQL sans vos données) au lieu de db/schema.rb . Vous utiliserez également différentes tâches Rake pour travailler avec structure.sql :

  • db:structure:dump au lieu de db:schema:dump
  • db:structure:load au lieu de db:schema:load

Tout le reste devrait fonctionner de la même manière.

Cette approche vous permet également d'utiliser d'autres éléments dans votre base de données qu'ActiveRecord ne comprendra pas :les contraintes CHECK, les déclencheurs, les valeurs par défaut des colonnes non simplistes, ...