Отправка формы с параметром для нового действия контроллера - PullRequest
0 голосов
/ 11 марта 2020
Rails 6
bootstrap 4

В моем books_controller.rb у меня есть:

def index
  @books = Book.select(:id, :name)
end

def new
    @book = Book.new
  end

def create
  @book = Book.new(book_params)
  respond_to do |format|
    if @book.save
      format.html { redirect_to @book, notice: 'Book was successfully created.' }
      format.json { render :show, status: :created, location: @book }
    else
      format.html { render :new }
      format.json { render json: @book.errors, status: :unprocessable_entity }
    end
  end
end

У меня есть таблица, в моих представлениях / books / index.htmlslim, у меня есть:

table.table.table-striped
  thead
    tr
      th Name
  tbody
    - @books.each do |book|
      tr
        td = book.name

В конце таблицы я хотел бы добавить форму, позволяющую пользователям добавлять книги, не переходя в отдельную форму, что-то вроде:

Я пытался:

= form_with url: new_book_path do |f|
  .form-inputs
    = f.label 'Add Book'
    = f.text_field :book_name
  .form-actions
    = f.submit    

И я также пытался:

= simple_form_for(@book) do |f|
  .form-inputs
    = f.input :book_name

Но ничего не происходит, когда я нажимаю на кнопку отправки, и я получаю следующее сообщение:

ActionController::RoutingError (No route matches [POST] "/bookd/new"):

Я также пытался:

= simple_form_for(@book || Book.new) do |f|
  .form-inputs
    = f.input :book_name

Но. Я получаю:

ActionView::Template::Error (undefined method `book_name` for #<Book:0x000007f9cce...>);

Еще одна мысль, это сделать ее ссылкой, что-то вроде:

= link_to new_book_path, :class => "btn btn-primary btn-lg"

Но как мне передать параметр book_name и какое действие контроллера это должно go к?

Вот мои маршруты:

books GET /books(.:format) books#index
POST /books(.:format) books#create
new_book GET /books/new(.:format) books#new
edit_book GET /books/:id/edit(.:format) books#edit
book GET /books/:id(.:format) books#show
PATCH /books/:id(.:format) books#update
PUT /books/:id(.:format) books#update
DELETE /books/:id(.:format) books#destroy

1 Ответ

1 голос
/ 11 марта 2020

В Rails вы не создаете ресурсы, публикуя по маршруту new - вы отправляете по маршруту сбора, например. /books. Новое действие просто используется для создания страницы с формой на ней.

Все еще очень удивительно, почему new_book_path вернет /bookd/new, но ошибка на самом деле правильная. new_book_path отвечает на GET - не POST. Это объясняется в Маршрутизация с внешней стороны .

Если вы на самом деле просто используете:

table.table.table-striped
  thead
    tr
      th Name
  tbody
    - @books.each do |book|
      tr
        td = book.name

= simple_form_for(@book || Book.new) do |f|
  .form-inputs
    = f.input :name # book_name is a typo?

Это правильно создаст форму с action="/books" method="POST".

Понятия не имею, что вы пытаетесь сделать с этим беспорядком:

= form_with url: new_book_path do |f|
  .form-inputs
    = f.label 'Add Book'
    = f.text_field :book_name
  .form-actions
    = f.submit    

    = simple_form_for(@book) do |f|
      .form-inputs
        = f.input :book_name

Но ни одна из HTML спецификаций не допускает вложенных <form> элементов и результаты могут быть дико непредсказуемыми. Например, кнопка отправки может отправить внутреннюю форму или внешнюю форму.

...