在混合任务中使用Ecto

时间:2017-01-04 11:13:55

标签: elixir phoenix-framework ecto

在Phoenix Framework应用程序中,我有一个模型Product,其字段为name。我想创建一个列出所有产品名称的混合任务。

在Ruby on Rails中,这将是解决问题的代码:

namespace :list do
  desc "List all products"
  task products: :environment do
    Product.all.each do |product|
      puts product.name
    end
  end
end

在凤凰城,我甚至无法从数据库中获取所有产品的列表。这是任务代码:

LIB /混合/任务/ list.product.ex

defmodule Mix.Tasks.List.Product do                                    
  use Mix.Task
  import Mix.Ecto
  alias App.Repo
  alias App.Product

  def run(_args) do
    products = Repo.all(Product)
  end
end

当我运行此任务时,我收到以下错误消息:

** (UndefinedFunctionError) function Ecto.Queryable.__using__/1 
is undefined or private

在此混音任务中,如何从数据库中获取所有产品?

2 个答案:

答案 0 :(得分:6)

ensure_started(Repo, [])方法的顶部添加run。对于某些查询表单,您可能还需要import Ecto.Query

defmodule Mix.Tasks.List.Product do                                    
  use Mix.Task
  import Mix.Ecto
  import Ecto.Query
  alias App.Repo
  alias App.Product

  def run(_args) do
    ensure_started(Repo, [])
    products = Repo.all(Product)
  end
end

答案 1 :(得分:1)

困难的方式:

defmodule Mix.Tasks.MyTask do
  use Mix.Task
  import Ecto.Query
  alias MyApp.Repo

  @start_apps [
    :postgrex,
    :ecto,
    :ecto_sql
  ]

  @repos Application.get_env(:my_app, :ecto_repos, [])

  def run(args) do
    start_services()

    # Run Ecto...

    stop_services()
  end

  defp start_services do
    Enum.each(@start_apps, &Application.ensure_all_started/1)
    Enum.each(@repos, & &1.start_link(pool_size: 2))
  end

  defp stop_services do
    :init.stop()
  end
end

或简单的方法;)

defmodule Mix.Tasks.MyTask do
  use Mix.Task
  import Ecto.Query
  alias MyApp.Repo

  def run(args) do
    Mix.Task.run("app.start")
    # Run Ecto...
  end
end