【问题标题】:Use interpolation in constraint function inside Ecto migrations.在 Ecto 迁移内的约束函数中使用插值。
【发布时间】:2018-08-15 02:51:29
【问题描述】:

我的一个应用程序中有以下迁移

use Ecto.Migration
  alias SnitchPayments.PaymentMethodCode

  @code PaymentMethodCode.hosted_payment() |> to_charlist() # this evaulautes to 'hpm'

  def change do
    create table("snitch_hosted_payments", comment: "payments made via hosted payments") do
      add(:transaction_id, :string)
      add(:payment_source, :string)
      add(:raw_response, :map)
      add(:payment_id, references("snitch_payments", on_delete: :delete_all), null: false)
      timestamps()
    end

    create unique_index("snitch_hosted_payments", :payment_id,
      comment: "one-to-one relationship")

    create constraint("snitch_hosted_payments",
      :hosted_payment_exclusivity,
      check: "payment_exclusivity(payment_id, #{@code}) = 1")
  end

如您所见,我试图在"payment_exclusivity(payment_id, #{@code}) = 1" 这一行中进行插值。但是,在运行迁移时出现错误

** (Postgrex.Error) ERROR 42703 (undefined_column): column "hpm" does not exist

“payment_exclusivity()”是 postgres 中的一个函数,我用给定的参数调用它。

如果我这样做,以下工作:

create constraint("snitch_hosted_payments",
          :hosted_payment_exclusivity,
          check: "payment_exclusivity(payment_id, 'hpm') = 1")

进行这种插值的正确方法是什么?我不想在这里硬编码值。

【问题讨论】:

  • 如果在#{@code} 中添加单引号会得到什么?
  • 用单引号将表达式括起来 '#{@code}',会有所不同吗?
  • check: fragment("payment_exclusivity(payment_id, ?) = 1", @code) 可能会起作用。
  • 谢谢,@AbdullahEsmail '#{@code}' 有效。 @mudasobwa 该方法看起来不错,但我不想在模块内导入Ecto.Query,因为单引号插值有效。谢谢大家的帮助。

标签: elixir ecto


【解决方案1】:

为了完整起见,我将在此处编写适用于 OP 的解决方案,因为此问题的答案可以标记为“已回答”。

建议的解决方案是用单引号将#{@code} 括起来:

check: "payment_exclusivity(payment_id, '#{@code}') = 1")

这对 Arjun 有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-23
    • 1970-01-01
    • 2023-03-22
    • 2016-12-24
    • 1970-01-01
    • 2013-09-10
    • 1970-01-01
    相关资源
    最近更新 更多