Elixir Phoenix框架:将插入数据库的次数限制为每天一次

Elixir Phoenix框架:将插入数据库的次数限制为每天一次,elixir,phoenix-framework,ecto,Elixir,Phoenix Framework,Ecto,我想为上班族做一个“每日祈祷午餐”应用程序,使用。我想制作的模型是Votation,每个Votation都包含许多嵌入式模式(阅读了解嵌入式模式的信息)。模型如下所示: defmodule WhereToLunch.Votation do use WhereToLunch.Web, :model schema "votations" do embeds_many :restaurants, Restaurant timestamps() end @doc ""

我想为上班族做一个“每日祈祷午餐”应用程序,使用。我想制作的模型是
Votation
,每个Votation都包含许多嵌入式
模式(阅读了解嵌入式模式的信息)。模型如下所示:

defmodule WhereToLunch.Votation do
  use WhereToLunch.Web, :model

  schema "votations" do
    embeds_many :restaurants, Restaurant
    timestamps()
  end

  @doc """
  Builds a changeset based on the `struct` and `params`.
  """
  def changeset(struct, params \\ %{}) do
    struct
    |> cast(params, [])
    |> validate_required([])
    |> #TODO: Is it !was_votation_inserted_today() ??
  end

  @doc """
  Returns `true` if a `Votation` object was already inserted in the database
  on the same day the function is called. Returns false otherwise.
  """
  def was_votation_inserted_today() do
    #TODO: How to check if a object was already inserted in the database
    #      on the same day the function is called?
  end
end

defmodule WhereToLunch.Restaurant do
  use Ecto.Model

  embedded_schema do
    field :name, :string
    field :votes, :integer, default: 0
  end
end

我想做的是不允许在表
中插入一个以上的
来启动。每天的votations
。这样做的最佳方法是什么

我会在表达式
date\u部分('day',inserted\u at)
上添加一个唯一索引,并让数据库处理唯一性

要创建唯一索引,请将以下内容添加到新迁移中:

def change do
  create index(:posts, ["date_part('day', inserted_at)"], name: "post_inserted_at_as_date", unique: true)
end
然后将
唯一\u约束添加到模型的
变更集/2

def changeset(...) do
  ...
  |> unique_constraint(:inserted_at, name: "post_inserted_at_as_date")
end
现在,数据库将不允许在插入的
中创建两篇当天发布的帖子:

iex(1)> Repo.insert Post.changeset(%Post{}, %{title: ".", content: "."})
[debug] QUERY OK db=0.3ms
begin []
[debug] QUERY OK db=3.4ms
INSERT INTO "posts" ("content","title","inserted_at","updated_at") VALUES ($1,$2,$3,$4) RETURNING "id" [".", ".", {{2017, 2, 6}, {16, 58, 0, 512553}}, {{2017, 2, 6}, {16, 58, 0, 517019}}]
[debug] QUERY OK db=0.9ms
commit []
{:ok,
 %MyApp.Post{__meta__: #Ecto.Schema.Metadata<:loaded, "posts">,
  comments: #Ecto.Association.NotLoaded<association :comments is not loaded>,
  content: ".", id: 1, inserted_at: ~N[2017-02-06 16:58:00.512553], title: ".",
  updated_at: ~N[2017-02-06 16:58:00.517019],
  user: #Ecto.Association.NotLoaded<association :user is not loaded>,
  user_id: nil}}
iex(2)> Repo.insert Post.changeset(%Post{}, %{title: ".", content: "."})
[debug] QUERY OK db=0.4ms
begin []
[debug] QUERY ERROR db=6.6ms
INSERT INTO "posts" ("content","title","inserted_at","updated_at") VALUES ($1,$2,$3,$4) RETURNING "id" [".", ".", {{2017, 2, 6}, {16, 58, 1, 695128}}, {{2017, 2, 6}, {16, 58, 1, 695138}}]
[debug] QUERY OK db=0.2ms
rollback []
{:error,
 #Ecto.Changeset<action: :insert, changes: %{content: ".", title: "."},
  errors: [inserted_at: {"has already been taken", []}], data: #MyApp.Post<>,
  valid?: false>}
iex(1)>Repo.insert Post.changeset(%Post{},%%{title:“.”,content:“.”)
[调试]查询OK db=0.3ms
开始[]
[调试]查询OK db=3.4ms
在“posts”(“content”,“title”,“inserted_at”,“updated_at”)中插入值($1,$2,$3,$4),返回“id”[“,”,{2017,2,6},{16,58,0,512553},{2017,2,6},{16,58,0,517019}]
[调试]查询OK db=0.9ms
提交[]
{好的,
%MyApp.Post{{uuuuu meta}:{35; exto.Schema.Metadata,
注释:#exto.Association.NotLoaded,
内容:“.”,id:1,插入地址:~N[2017-02-06 16:58:00.512553],标题:“.”,
更新地址:~N[2017-02-06 16:58:00.517019],
用户:#exto.Association.NotLoaded,
用户_id:nil}
iex(2)>Repo.insert Post.changeset(%Post{},%%{title:“.”,content:“})
[调试]查询OK db=0.4ms
开始[]
[调试]查询错误db=6.6ms
在“posts”(“content”,“title”,“inserted_at”,“updated_at”)中插入值($1,$2,$3,$4),返回“id”[“,”,{2017,2,6},{16,58,1,695128},{2017,2,6},{16,58,1,695138}]
[调试]查询OK db=0.2ms
回滚[]
{:错误,
#外部变更集}

利用数据库在日期字段上的唯一索引。