【问题标题】:Default value for a field in changeset变更集中字段的默认值
【发布时间】:2018-07-02 12:46:11
【问题描述】:

我有一个模型和变更集方法。我想要一个可选字段,如果它没有传递给chargeset,我想设置一个默认值。我该怎么做?

【问题讨论】:

  • 在发送给cast之前先做params = Map.put_new(params, "field", default_value)怎么样?
  • @Dogbert 这是公认的默认方式吗?例如用户的角色:params = Map.put_new(params, :role_id, 2)

标签: elixir phoenix-framework


【解决方案1】:

当您创建架构时,您可以通过将:default 原子传递给它一个默认值。

schema "foo" do
  field :name, :string, default: "bar"
end

【讨论】:

  • 你能默认这样的关联吗?
  • 是的。请记住,默认键是在编译时计算的。因此,如果您进行数据库访问以查找外键,它将仅在编译时进行数据库访问,而不是每次插入。
【解决方案2】:

如果您的需求很简单,贾斯汀的回答绝对是最优雅的,但就我而言,我需要更多的灵活性。我需要能够生成一个独特的、加密安全的值。

我是在我的变更集管道中完成的:

def changeset(build_proxy, attrs) do
  build_proxy
  |> cast(attrs, [:avatar, :channel, :username, :service_base_url])
  |> gen_api_token_if_empty()
  |> validate_required([:avatar, :channel, :username, :service_base_url])
end                                                                                   

defp gen_api_token_if_empty(changeset) do
  case get_change(changeset, :api_token) do
    nil -> put_change(changeset, :api_token, gen_api_token())
     "" -> put_change(changeset, :api_token, gen_api_token())
      _ -> changeset
  end
end

defp gen_api_token() do
  :crypto.strong_rand_bytes(80)
  |> Base.url_encode64
  |> binary_part(0, length)
end

【讨论】:

  • 更好的解决方案可能是创建您自己的 ecto 类型并让它为您自动生成值。
  • @JustinWood 感谢您的建议!这听起来更好。我现在是个万能药菜鸟,hexdocs.pm/ecto/Ecto.Type.html 你指的是什么?
  • 在您的示例中,我认为 gen_api_token_if_empty/1 总是会“认为”该字段为空 - 您没有在 @ 列表中包含 :api_tokencast/3 的调用中的987654325@ 参数。
猜你喜欢
  • 2011-08-24
  • 1970-01-01
  • 1970-01-01
  • 2017-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-21
相关资源
最近更新 更多