2017-09-12 3 views
0

Comment puis-je utiliser les attributs de module pour définir Repo à la volée? Par exemple, je staging et production envs:Affecter Repo à l'attribut de module?

defmodule Test do 
    @repo "staging" 

    def repo do 
    case @repo do 
     "staging" -> alias MyApp.Schools.staging.Repo, as: SRepo 
     "production" -> alias MyApp.Schools.prod.Repo, as: SRepo 
    end 
    end 
end 

si je fais: Test.repo je reçois: Elixir.MyApp.Schools.staging.Repo , pourquoi je n'ai pas obtenu ce que j'attendais MyApp.Schools.staging.Repo?

EDIT

J'ai aussi essayé simplement de renvoyer le module sans alias:

def repo do 
     case @repo do 
      "staging" -> MyApp.Schools.staging.Repo 
      "production" -> MyApp.Schools.prod.Repo 
     end 
     end 

mais, je suis Elixir.MyApp.Schools.staging.Repo

+0

Cela ne fonctionnera pas comme ceci. ["import/2, require/2 et alias/2 sont appelés des directives et ont tous une portée lexicale.Cela signifie que vous pouvez configurer des alias dans des fonctions spécifiques et cela n'affectera pas la portée globale."] (https: // hexdocs .pm/elixir/Kernel.SpecialForms.html # alias/2) Pourquoi voulez-vous faire cela? Peut-être qu'il y a une autre façon de résoudre votre problème. – Dogbert

+0

S'il vous plaît cocher EDIT bove, ce que j'essaie de faire, est d'utiliser Repo sélectivement basé sur un paramètre envoyé par requête, ainsi, il devrait être déterminé lors de l'exécution de la requête http, DB de production et DB de production, et nous devons Choisissez DB en fonction du paramètre envoyé. – simo

+0

peut-être ce que j'essaie de faire est anti pattern? Avoir un serveur pour la mise en scène et la production est une mauvaise idée? – simo

Répondre

0

Si vous voulez vraiment changer la prise en pension sur la base d'une valeur dans les paramètres reçus par les fonctions du contrôleur (au lieu de la façon la plus courante d'exécuter une instance distincte de l'application, une avec MyApp.Repo pointant vers une mise en scène et une pointant vers la production n), vous pouvez créer une fonction qui renvoie simplement le module Repo approprié en fonction des paramètres, puis appeler des fonctions sur la valeur renvoyée.

defmodule MyApp do 
    def repo("staging"), do: MyApp.Staging.Repo 
    def repo("production"), do: MyApp.Production.Repo 
end 

defmodule MyApp.PostController do 
    ... 
    # env can be "staging" or "production" 
    def index(conn, %{"env" => env}) do 
    repo = MyApp.repo(env) 
    render conn, "index.html", posts: repo.all(Post) 
    end 
end