Ir al contenido

Editar una fila ​

Traducción automática

Esta página se tradujo automáticamente del inglés y todavía no la revisó un hablante nativo; las correcciones son bienvenidas en GitHub. Si algo no coincide, vale el original en inglés.

Tarea: una página que edita un libro, a la que se llega desde la lista.

yaml
# Recipe: open a form with a row's values and save it back.
paths:
  components: ./components
  migrations: ./migrations

datasources:
  db:
    driver: sqlite
    database: ./data/books.db
sql
CREATE TABLE books (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    title VARCHAR(120) NOT NULL,
    genre TEXT NOT NULL CHECK (genre IN ('novel', 'poetry', 'essay'))
);

INSERT INTO books (title, genre) VALUES ('Dom Casmurro', 'novel'), ('Libertinagem', 'poetry');

La lista enlaza cada libro a /book/{id}:

xml
<q:component name="Books">
  <q:query name="books" datasource="db">
    SELECT id, title, genre FROM books ORDER BY id
  </q:query>

  <ui:window title="Books">
    <q:if condition="flash">
      <ui:alert variant="success">{flash}</ui:alert>
    </q:if>
    <q:loop query="books">
      <ui:hbox gap="sm">
        <ui:text>{books.title} ({books.genre})</ui:text>
        <ui:link to="/book/{books.id}">Edit</ui:link>
      </ui:hbox>
    </q:loop>
  </ui:window>
</q:component>

components/book/[id].q responde a /book/2 con id = 2. La acción toma title y genre de la tabla (Un formulario a partir de la tabla) y values="{book}" abre el formulario con los valores de la fila. Basta con una consulta de una fila.

xml
<q:component name="EditBook">
  <!-- /book/2 gives id = 2. The action takes title and genre, with their
       rules, from the table (UI-10); id comes from the URL. -->
  <q:action name="save" method="POST" table="books" datasource="db" columns="title,genre">
    <q:query name="saved" datasource="db">
      UPDATE books SET title = :title, genre = :genre WHERE id = :id
      <q:param name="title" value="{title}" type="string" />
      <q:param name="genre" value="{genre}" type="string" />
      <q:param name="id" value="{id}" type="integer" />
    </q:query>
    <q:redirect url="/" flash="Saved: {title}" />
  </q:action>

  <q:query name="book" datasource="db">
    SELECT id, title, genre FROM books WHERE id = :id
    <q:param name="id" value="{id}" type="integer" />
  </q:query>

  <ui:window title="Edit a book">
    <q:if condition="book_result.recordCount == 0">
      <ui:alert variant="danger">There is no book {id}.</ui:alert>
    </q:if>
    <q:else>
      <!-- values= opens the form with the row's values; a one-row query works. -->
      <ui:form on-submit="save" values="{book}" submit="Save" />
    </q:else>
    <ui:link to="/">Back</ui:link>
  </ui:window>
</q:component>
xml
<q:test name="the form opens on the row's page" page="/book/2">
  <test:visit />
  <test:expect text="Edit a book" />
  <test:expect text="Save" />
  <test:expect no-text="There is no book" />
</q:test>

<q:test name="saving changes only that row" page="/book/2">
  <test:submit action="save" title="Libertinagem (1930)" genre="poetry" />
  <test:expect redirect="/" flash="Saved: Libertinagem (1930)" />
  <test:expect table="books" count="1" where="id = 2 AND title = 'Libertinagem (1930)'" />
  <test:expect table="books" count="1" where="id = 1 AND title = 'Dom Casmurro'" />
  <test:expect text="Libertinagem (1930) (poetry)" />
</q:test>

<q:test name="the table's rules still apply" page="/book/2">
  <test:submit action="save" title="Libertinagem" genre="comic" />
  <test:expect error="genre" message="Must be one of: novel, poetry, essay" />
  <test:expect table="books" count="1" where="id = 2 AND genre = 'poetry'" />
</q:test>

<q:test name="a book that does not exist says so" page="/book/99">
  <test:visit />
  <test:expect text="There is no book 99." />
  <test:expect no-text="Save" />
</q:test>
text
tests/edit.test.q
  PASS  the form opens on the row's page
  PASS  saving changes only that row
  PASS  the table's rules still apply
  PASS  a book that does not exist says so
4 passed, 0 failed

Ver UI-10.

Licencia MIT · Hecho con VitePress