2015-09-30 8 views
11

は、私は私のUserモデルを持っているフェニックスのアプリで動作していないユニークインデックス制約は、次のように私のフェニックスアプリで

defmodule MyApp.Repo.Migrations.CreateUser do 
    use Ecto.Migration 

    def change do 
    create table(:users) do 
     add :email, :string 
     add :username, :string 
     add :crypted_password, :string 

     timestamps 
    end 

    create unique_index(:users, [:email]) 
    create unique_index(:users, [:username]) 
    end 
end 

をそして私は私のregistration_controller_exとしてを持っています次の:だから

defmodule MyApp.RegistrationController do 
    use MyApp.Web, :controller 
    alias MyApp.User 

    def new(conn, _params) do 
    changeset = User.changeset(%User{}) 
    render conn, changeset: changeset 
    end 

    def create(conn, %{"user" => user_params}) do 
    changeset = User.changeset(%User{}, user_params) 

    if changeset.valid? do 
     user = MyApp.Registration.create(changeset, MyApp.Repo) 
     conn 
     |> put_flash(:info, "Your account was created") 
     |> redirect(to: "/") 
    else 
     conn 
     |> put_flash(:info, "Unable to create account") 
     |> render("new.html", changeset: changeset) 
    end 
    end 
end 

を、私はかなり確信しているすべての私のusernameと012でUserのフィールドは一意のインデックスです。また、User.changesetを検証するためにunique_constraintを呼び出すことによって、それらが一意であることを確認します。しかし、自分のインターフェースで、preivously作成されたものと同じ電子メールとユーザー名を持つユーザーを作成すると、チェンジセットが検証され、ユーザーは作成されます。 (実際には作成されていませんが、データベースを調べると何も追加されません)

私のサーバーログには次のような内容があります。本当です。

[debug] BEGIN [] OK query=139.3ms queue=8.2ms 
[debug] INSERT INTO "users" ("crypted_password", "email", "inserted_at", "updated_at", "username") VALUES ($1, $2, $3, $4, $5) RETURNING "id" ["$2b$12$MN1YxFUGLMIJYXseZn0sjuuVs9U1jRdYtRr9D8XQsAqdh.D2sRRXa", "[email protected]", {{2015, 9, 30}, {11, 7, 25, 0}}, {{2015, 9, 30}, {11, 7, 25, 0}}, "username"] ERROR query=5.5ms 
[debug] ROLLBACK [] OK query=0.4ms 

また、私は(そのような最小パスワード長や他のもののように)私のUser.changeset機能で探して他のものは、ユーザーに報告を取得し、うまく働いています。報告されていない:email:usernameのユニークなインデックスです。

答えて

17

unique_constraintはデータベースによってチェックされるため、レコードの挿入時にのみトリガーされます。 changeset.valid?を呼び出すと制約がチェックされないため、この場合はtrueを返します。あなたが挿入し、そのように作用レポのリターンタプルをチェックする必要があります。

def create(conn, %{"user" => user_params}) do 
    changeset = User.changeset(%User{}, user_params) 
    case MyApp.Repo.insert changeset do 
    {:ok, changeset} -> 
     conn 
     |> put_flash(:info, "Your account was created") 
     |> redirect(to: "/")  
    {:error, changeset} -> 
     conn 
     |> put_flash(:info, "Unable to create account") 
     |> render("new.html", changeset: changeset)  
    end 
end 

今、あなたのchangeset.errorsが濃縮されて、あなたはそれが機能しなかったchangeset.errors[:email]

+0

でエラーを取得することができるはずです。私は問題があります:registration_controller.ex:15:function changeset/0 undefined –

+0

後継の場合、上記の行はわずかに変更する必要があります:changset = User.changeset(%User {}、user_params) – pip

関連する問題