2017-02-06 5 views
1

Phoenix Frameworkを使用して、ここの職場の人々のための「毎日の投票弁当」アプリを作成したいと考えています。私が考えたモデルはVotationで、各Votationには多くの埋め込みスキーマ(埋め込みスキーマの情報についてはhereを読んでください)が含まれています。モデルは次のように探しています:フェニックスフレームワーク:limitデータベースに1日に挿入

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 

私は何をしたいことは一日あたりのテーブル内の複数のInsertwhere_to_launch.votationsを許可しないことです。それを行うための最良の方法は何ですか?

+1

データベースのユニークなインデックスを日付フィールドで活用します。 –

答えて

3

私は式date_part('day', inserted_at)に一意のインデックスを追加して、データベースに一意性を扱わせます。

def change do 
    create index(:posts, ["date_part('day', inserted_at)"], name: "post_inserted_at_as_date", unique: true) 
end 

してからモデルのchangeset/2unique_constraintを追加します:

def changeset(...) do 
    ... 
    |> unique_constraint(:inserted_at, name: "post_inserted_at_as_date") 
end 

データベースは現在、2つのポストを作成する許可しないだろう、一意のインデックスを作成して新しい移行に以下を追加するには

同じ日にinserted_at

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>} 
関連する問題