Qual è il modo di gestire le associazioni e i moduli annidati nel framework Phoenix? Come si creerebbe un modulo con attributi nidificati? Come lo si maneggia nel controller e nel modello?Come gestire associazioni e moduli annidati nel framework Phoenix?
risposta
C'è un semplice esempio di gestione della situazione 1-1.
Immaginiamo di avere una e una Engine
modelli Car
e ovviamente un Car
has_one Engine
. Quindi c'è il codice per il modello di auto
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
e il modello del motore
defmodule MyApp.Engine do
use MyApp.Web, :model
schema "engines" do
field :type, :string
belongs_to :car, MyApp.Car
timestamps
end
def changeset(model, params \\ :empty) do
model
|> cast(params, ~w(type), ~w())
|> validate_length(:type, max: 10, message: "No way it's that long")
end
end
semplice modello per la forma ->
<%= 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 %>
ed il regolatore ->
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, "new.html", changeset: car_changeset
end
end
end
e un interessante post sul blog l'argomento che può chiarire anche alcune cose ->here
Si è verificato lo stesso problema con una relazione has_many
. Purtroppo, un Car
non può avere molti Engines
, quindi mi piacerebbe prendere lo stesso esempio in questo blogpost, di un TodoList
, con molte TodoItems
TodoList
modello:
defmodule MyApp.TodoList do
use MyApp.Web, :model
schema "todo_lists" do
field :title, :string
has_many :todo_items, MyApp.TodoItem
timestamps
end
def changeset(model, params \\ :{}) do
model
|> cast(params, [:title])
|> cast_assoc(:todo_items)
end
end
TodoItem
modello:
defmodule MyApp.TodoItem do
use MyApp.Web, :model
schema "todo_items" do
field :body, :string
belongs_to :todo_list, MyApp.TodoList
timestamps
end
def changeset(model, params \\ :{}) do
model
|> cast(params, [:body])
end
end
Ecco la creazione del modulo TodoList
. Per semplificare le cose, aggiungiamo un elemento per ora.
<%= form_for @changeset, todo_lists_path(@conn, :create), fn f -> %>
<%= text_input f, :title %>
<%= inputs_for f, :todo_items, fn i -> %>
<%= text_input i, :body %>
<% end %>
<button name="button" type="submit">Create</button>
<% end %>
Questo è il modo in TodoListController
sarebbe simile. Il metodo create
era il più difficile da ottenere. Ho dovuto scavare nei test Ecto per trovare un modo per farlo funzionare. Link
defmodule MyApp.TodoListController do
use MyApp.Web, :controller
alias MyApp.TodoList
alias MyApp.TodoItem
def new(conn, _params) do
todo_item = TodoItem.changeset(%TodoItem{})
changeset = TodoList.changeset(%TodoList{todo_items: [todo_item]})
render conn, "new.html", changeset: changeset
end
def create(conn, %{"todo_list" => todo_list_params}) do
todo_item_changeset =
TodoItem.changeset(%TodoItem{}, todo_item["todo_items"]["0"])
changeset =
TodoList.changeset(%TodoList{}, %{title: todo_list_params["title"]})
|> Ecto.Changeset.put_assoc(:todo_items, [todo_item_changeset])
case Repo.insert(changeset) do
{:ok, company} ->
conn
|> put_flash(:info, "TodoList created!")
|> redirect(to: page_path(conn, :index))
{:error, changeset} ->
conn
|> render "new.html", changeset: changeset
end
end
end
http://pranavsingh.co/storing-nested-associations-with-phoenix-forms/
Qualche idea su come aggiungere più oggetti, aggiungendoli/rimuovendoli in modo dinamico nella forma? –
- 1. Qual è il modo corretto di gestire i moduli annidati/i changeset ecto in Phoenix?
- 2. miscelazione Scopes e Associazioni in Phoenix/Ecto
- 3. Come convalidare la presenza nel framework Phoenix?
- 4. Come concatenare due tag nel framework phoenix?
- 5. Come ottenere l'url corrente nel framework phoenix
- 6. Phoenix Ecto come gestire NoResultsError
- 7. Uso dei percorsi polimorfe con associazioni annidati
- 8. ASP.NET MVC 4 - Modelli annidati - Come impostare le associazioni appropriate?
- 9. Come caricare la vista interna nel framework Phoenix?
- 10. Callback di Phoenix Framework
- 11. Come disabilitare selettivamente il controllo CSRF nel framework Phoenix
- 12. Come gestire raccolte e associazioni di doctrine di grandi dimensioni
- 13. Moduli nel framework di gioco Scala
- 14. Come inviare e-mail con il framework Phoenix
- 15. Utilizzo di Phoenix Framework senza Ecto
- 16. Elenco di modelli annidati in moduli backbone
- 17. Come gestire i moduli Node.JS interni
- 18. Qual è la differenza tra `def` e` defp` nel Phoenix Framework?
- 19. Pattern URL annidati in Django REST Framework
- 20. ricerca a testo completo per phoenix framework
- 21. Framework dei moduli CSS?
- 22. convalidare i moduli annidati senza influire sul modulo principale
- 23. Entity Framework - Riflessione su chiavi esterne e relazioni/associazioni
- 24. Come aggiungere un messaggio di errore personalizzato per un campo richiesto nel framework Phoenix
- 25. Come usare SASS/SCSS con il framework Phoenix?
- 26. Come creare una vista globale in Phoenix Framework?
- 27. Phoenix Framework: come instradare il tipo di supporto personalizzato?
- 28. Moduli annidati in rotaia - accesso all'attributo in has_many relation
- 29. Rails e routing annidati di rails: come suddividere i controller?
- 30. Gestire i moduli AngularJS versione e release utilizzando Grunt
L'esempio può avere alcuni piccoli errori da quando non ho avuto la possibilità di testare proprietà o essere scritto in modo non è un esattamente corretto visto che sono nuovo di questo quadro me stesso ma io spero che possa aiutare qualcuno a risparmiare un po 'di tempo a capire quelle cose da solo. Sto solo cercando di trovare le risposte ad alcune domande più semplici visto che non ci sono molte informazioni sull'argomento – JustMichael
Il problema con questa soluzione se, ad esempio, se Car 'avesse un vincolo come l'unicità per il suo nome, allora la transazione fallirebbe e nessun errore sarebbe dato per il modulo. Sono bloccato in questo: http://stackoverflow.com/a/38035026?noredirect=1 – masylum
Ecco un test che mostra come si farebbe l'inserto annidato in ecto 2, https://github.com/elixir-ecto/ ecto/blob/6f1971f4120b84e1a441792feb77ba451c4fc783/integration_test/cases/repo.exs # L720 – opsb