- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我刚开始吃 Phoenix ,我不太了解一件事,我搜索并看到模式是数据库结构和模型具有高级别的逻辑处理,但在 Phoenix 我们只有模式,例如,如果我会做一个密码哈希,它应该在用户模式中?或者我应该把它放在 Controller 中?
最佳答案
一般来说,您希望您的 MVC 应用程序具有“瘦 Controller ”——这是适用于多种语言的建议。在某些语言/框架中,这很关键,因为测试 Controller 可能非常困难。尽管使用 Elixir 等函数式语言和 Phoenix 等结构良好的框架测试 Controller 相对简单,但您仍应尽可能保持 Controller 精简。简而言之, Controller 应该将服务模块(在 Phoenix 中通常称为“上下文”)与 View 连接起来。通常它们根本没有很多逻辑。
“模式”可能是一个令人困惑的术语——花点时间了解不同的数据库使用不同的术语来指代(或多或少)相同的组件。例如。 MySQL 中的“数据库”在 Oracle 或 Postgres 中称为“模式”。在 Ecto 中,“模式”类似于许多其他框架中的 ORM“模型”:Ecto 模式在代码中表示特定数据库表的“形状”(所以也许这就是它们使用相同术语的原因)。
但是,在您的情况下,密码哈希的计算字段之类的内容应该与 Ecto 模式位于同一模块中。 (是的,当 Ecto 在代码中定义表格的形状时,它做了一些宏魔术,但它仍然是一个模块,并且推荐放置 changeset
函数,这些函数在数据进入数据库之前处理验证和变异数据) .
如果您发现自己想知道某些功能应该放在哪里,请问问自己,如果用户输入来自 CLI 而不是来自 Web,您会将代码放在哪里。如果你有一个 CLI 混合任务创建一个带密码的用户,你会使用 Web Controller 吗?不,您不会: Controller 只是将 Web 请求/响应与底层模型/模式连接起来的中间人。您不希望仅仅因为您想为 CLI 脚本创建计算密码哈希的代码而复制它,这样您就有了放置它的逻辑位置:在模式中。
Ecto 变更集允许您在进入数据库的过程中修改数据。在某些框架中,您可能会听到这被称为“突变”或“计算字段”。
这是一个计算“created_at”字段的示例(是的,您可以在数据库中执行此操作,但它是如何在代码中执行计算字段的有用示例):
@doc false
def changeset(user, attrs) do
user
|> cast(attrs, [:username,:email])
|> validate_required([:username,:email])
|> add_created_at()
|> unique_constraint(:username)
|> unique_constraint(:email)
end
defp add_created_at(changeset) do
case changeset do
%Ecto.Changeset{
valid?: true,
changes: _user
} ->
put_change(
changeset,
:created_at,
DateTime.utc_now
|> DateTime.truncate(:second)
)
_ ->
changeset
end
end
Argon2
包裹。这还添加了一个字段,用于标识用于散列密码的算法(作为字符串,可供引用):
def changeset(user, attrs) do
user
|> cast(attrs, [:username, :password])
|> validate_required([:username, :password])
|> validate_length(:password, min: 8, max: 100)
|> unique_constraint(:username)
|> put_password_hash()
end
defp put_password_hash(changeset) do
case changeset do
%Ecto.Changeset{
valid?: true,
changes: %{
password: plain_text
}
} ->
put_change(changeset, :password_hash, Argon2.hash_pwd_salt(plain_text))
|> put_change(:algorithm, "argon2")
_ ->
changeset
end
end
关于elixir - 模式和模型有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61491863/
在 ruby 脚本中,我可以简单地执行以下操作: require 'some-gem' SomeGem.do_something! 如何在 elixir exs 脚本中做类似的事情而不创建一个全新
我正在尝试与 Elixir 中的字符串位进行比较 - 如果它们相等,则 if block 触发或 else block 应该触发。 def show(conn, %{"id" => id}) do
我需要转换这个字符串 "/{foo}/{bar}.{format}" 在 "/#{a["foo"]}/#{a["bar"]}.#{a["format"]}" 因为我有一个包含这些属性的列表。例如 a[
我想在我的 Phoenix 应用程序中注册 2 个根主管,有什么理由不这样做吗? 例子如下 defmodule MyApp.Application do use Application imp
在一个 Elixir 项目中 mix.exs文件,我们像这样包含依赖项 defp deps(_) do [ {:phoenix, "~> 0.6.1"}, {:ecto,
我定义了一个与 guide-started 相关的环境变量,我的 mix.exs 是 defmodule Basic.Mixfile do use Mix.Project def projec
我正在使用 elixir lang getting started 学习 Elixir 编程,而我堆满了 record brace syntax . 这是示例: defrecord FileInfo,
我在谷歌上搜索了很多,但找不到任何关于这个主题的东西——要么 Elixir 的语言太年轻,要么我用错误的术语搜索。 我正在学习 Jose Valim 的 Elixir Portal 教程 (https
Elixir 是否支持类似于 Clojure 的命名匿名函数? 例如,我想做这样的事情: fib_fun = fn fib n -> if n fun = fn (n, _) when
我刚开始学习 Elixir,但有几种 OOP 语言的编程背景,主要是 Ruby。我找到了如何在模块内定义结构的示例: defmodule Example.User do defstruct nam
我定义了一个 Foo像这样的模块: defmodule Foo do def hello(x = %{name: name}) do IO.inspect [x, name] end
有人可以提出一个建议,如何一次用一批x迭代列表BUT吗? 例如: 如果功能存在: ["1","2","3","4","5","6","7","8","9","10"].step(5)|> IO.put
我正在开发 ubuntu 14.04 LTS。我按照 offical website 中给出的说明安装了 elixir在控制台中运行以下行,一切正常 Add Erlang Solutions repo
嗨,Elixir 程序员。 我有大约 2.500 首音乐轨道的列表,我想按不同的参数对其进行排序,例如轨道的标题。 排序应该不区分大小写。 下面的代码有效,但需要大约 100 毫秒到 130 毫秒来对
Elixir 有语言规范文档吗?如果是,它在哪里? Elixir 网站有 library documentation ,我在 guards 上找到了一些文档和 operators ,但我没有找到语言规
阅读有关 Elixir 不变性以及它如何尽可能避免内存复制的文章,这似乎是唯一可能的解释,但我还没有在任何地方看到它的明确说明。例如,当将一个新元素附加到列表时,它被描述为该操作恰好需要 n 个步骤,
我想知道是否有一种方法可以捕获绝对光标位置 在 Elixir 的命令行中。 我知道我必须使用以下 ansi 转义序列\033[6n, 并在执行后: echo -en "\033[6n" 打印出我正在寻
在 Elixir 文档中,他们一直使用带有斜线的奇怪符号,例如: is_boolean/1 IO.puts/1 String.length/1 is_function/2 ++/2 我只是猜测,但我认
我已经开始阅读有关 Elixir 编程语言的信息。 我明白那个: 它是功能性的 它是动态的,但支持@spec 它基于 Erlang VM 我的问题是:它是否有某种 GC? 最佳答案 是的,Erlang
我写了这个测试用例: assert_raise ArgumentError, myFn(a,b) 但它并没有达到我期望的效果。 myFn引发ArgumentError(do: raise Argume
我是一名优秀的程序员,十分优秀!