解决方法
有一个处理1-1情况的简单例子.
想象一下,我们有一辆汽车和一个发动机型号,显然是一辆汽车has_one发动机.所以有汽车模型的代码
defmodule MyApp.Car do use MyApp.Web,:model schema "cars" do field :name,:string has_one :engine,MyApp.Engine timestamps end def changeset(model,params \\ :empty) do model |> cast(params,~w(name),~w()) |> validate_length(:name,min: 5,message: "No way it's that short") end end
和发动机型号
defmodule MyApp.Engine do use MyApp.Web,:model schema "engines" do field :type,:string belongs_to :car,MyApp.Car timestamps end def changeset(model,~w(type),~w()) |> validate_length(:type,max: 10,message: "No way it's that long") end end
表单的简单模板 – >
<%= form_for @changeset,cars_path(@conn,:create),fn c -> %> <%= text_input c,:name %> <%= inputs_for c,:engine,fn e -> %> <%= text_input e,:type %> <% end %> <button name="button" type="submit">Create</button> <% end %>
和控制器 – >
defmodule MyApp.CarController do use MyApp.Web,:controller alias MyApp.Car alias MyApp.Engine plug :scrub_params,"car" when action in [:create] def new(conn,_params) do changeset = Car.changeset(%Car{engine: %Engine{}}) render conn,"new.html",changeset: changeset end def create(conn,%{"car" => car_params}) do engine_changeset = Engine.changeset(%Engine{},car_params["engine"]) car_changeset = Car.changeset(%Car{engine: engine_changeset},car_params) if car_changeset.valid? do Repo.transaction fn -> car = Repo.insert!(car_changeset) engine = Ecto.Model.build(car,:engine) Repo.insert!(engine) end redirect conn,to: main_page_path(conn,:index) else render conn,changeset: car_changeset end end end