2016-07-25 73 views
0

第一:我找到了這個topic,但它不起作用。Elixir Ecto插入空的belongs_to

我有兩個型號

Council(1)<->(n)Department 

之間的關係,我想插入理事會未經關係到一個部門。

我有了這個外生模式:

schema "councils" do 
    field :name, :string 
    field :description, :string 
    belongs_to :department, Db2.Department 
    many_to_many :students, Db2.Student, join_through: Db2.StudentCouncil 
    many_to_many :periods, Db2.Period, join_through: Db2.StudentCouncil 

    timestamps() 
end 

這個SQL模式:

CREATE TABLE public.councils 
(
    id integer NOT NULL DEFAULT nextval('councils_id_seq'::regclass), 
    name character varying(255), 
    description character varying(255), 
    department_id integer, 
    inserted_at timestamp without time zone NOT NULL, 
    updated_at timestamp without time zone NOT NULL, 
    CONSTRAINT councils_pkey PRIMARY KEY (id), 
    CONSTRAINT councils_department_id_fkey FOREIGN KEY (department_id) 
     REFERENCES public.departments (id) MATCH SIMPLE 
     ON UPDATE NO ACTION ON DELETE NO ACTION 
) 

文檔說cast/4已被棄用,但鳳凰在自身變更與cast/3 & validate_required/3 。我只加了department讓我有以下變更:

def changeset(struct, params \\ %{}) do 
    struct 
    |> cast(params, [:name, :description, :department_id]) 
    |> validate_required([:name]) 
    |> unique_constraint(:name) 
    |> assoc_constraint(:department) 
end 

對於使用默認phoenix.html表單元素的形式我'。 當我提交表單鳳說以下內容:

[debug] QUERY OK db=1.2ms queue=0.1ms 
SELECT u0."id", u0."uid", u0."is_admin", u0."is_staff", u0."password_hash", u0."inserted_at", u0."updated_at" FROM "users" AS u0 WHERE (u0."id" = $1) [1] 
[debug] Processing by Db2.CouncilController.create/2 
Parameters: %{"_csrf_token" => "KwpdFCZ/bFN9fwkcXSAYLhRCIzgOAAAAXeoEa4+d1MoT7SvzZpgOdg==", "_utf8" => "✓", "council" => %{"department_id" => "", "description" => "", "name" => "test2"}} 
    Pipelines: [:browser] 
[debug] QUERY OK db=1.2ms queue=0.1ms 


#Ecto.Changeset<action: :insert, changes: %{description: "", name: "test2"}, 
    errors: [department_id: {"is invalid", [type: :id]}], data: #Db2.Council<>, 
    valid?: false> 

回答

1

的問題是,你要發送一個空字符串作爲department_id,而不是nil。空字符串不轉換爲nil自動:

iex(1)> MyApp.Post.changeset %MyApp.Post{}, %{"title" => "Hello"} 
#Ecto.Changeset<action: nil, changes: %{title: "Hello"}, errors: [], 
data: #MyApp.Post<>, valid?: true> 
iex(2)> MyApp.Post.changeset %MyApp.Post{}, %{"title" => "Hello", "user_id" => nil} 
#Ecto.Changeset<action: nil, changes: %{title: "Hello"}, errors: [], 
data: #MyApp.Post<>, valid?: true> 
iex(3)> MyApp.Post.changeset %MyApp.Post{}, %{"title" => "Hello", "user_id" => "1"} 
#Ecto.Changeset<action: nil, changes: %{title: "Hello", user_id: 1}, errors: [], 
data: #MyApp.Post<>, valid?: true> 
iex(4)> MyApp.Post.changeset %MyApp.Post{}, %{"title" => "Hello", "user_id" => ""} 
#Ecto.Changeset<action: nil, changes: %{title: "Hello"}, 
errors: [user_id: {"is invalid", [type: :id]}], data: #MyApp.Post<>, 
valid?: false> 

你可以明確設定department_idnil調用changeset之前,或使用鳳凰的scrub_params插件,它做同樣的事情對所有空字符串:

# web/controllers/council_controller.ex 
plug :scrub_params, "council" when action in [:create] 

(將"council"更改爲字段名稱,將[:create]更改爲您接受該字段的操作列表。)

+0

wo?t?謝謝。奇蹟般有效 :) –