Rails СУХИЕ вложенные формы для нескольких представлений

#ruby-on-rails #nested #dry

#ruby-on-rails #вложенные #сушит

Вопрос:

Я пытаюсь создать СУХУЮ форму, которую я мог бы использовать в качестве form_fields для других вложенных форм в другом представлении. У меня возникли 2 проблемы.

  1. Я хочу, чтобы у _form partial не было кнопки отправки, а скорее была эта кнопка в самой форме. Однако нажатие кнопки отправки в ее текущем месте ничего не делает??
  2. Форма отлично отображается в ее текущем состоянии. Если я переместу кнопку отправки на _form просто чтобы увидеть, что она сохраняется, я получу ошибку маршрутизации для uninitialized constant UsersController ?

Мой код:

routes.rb

 devise_for :users

resources :users do
  resources :projects
end
  

модель user.rb — я использую Devise.

 class User < ApplicationRecord
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable

  validates :password, :presence => true,
                       :on => :create,
                       :format => {:with => /A.*(?=.{8,})(?=.*d)(?=.*[@#$%^amp; =]).*Z/ }

  has_many :projects, inverse_of: :user
  accepts_nested_attributes_for :projects

end
  

модель projects.rb

 class Project < ApplicationRecord
  belongs_to :user, inverse_of: :projects
  ...
end
  

projects_controller.rb

 class ProjectsController < ApplicationController

...

def new
  @project = current_user.projects.build
end

def create
  @project = current_user.projects.new(project_params)
  if @project.save
    redirect_to root_path, notice: 'Your project is being reviewed. We will be in contact soon!'
  else
    render :new
  end
end

...

private

...

def project_params
  params.require(:project)
        .permit(
          :user_id, :project_type_id, :name, :industry_id, 
          :description, :budget_id, :project_status_id, feature_ids:[], addon_ids:[]
        )
end

end
  

_form.html.erb частичный просмотр

 <%= form_for @project do |f| %>      
  <div class="project_form">
    <ol>
      <div class="field entry_box">
        <li><%= f.label "Give your project a name" %>
        <%= f.text_field :name, placeholder: "A short name", class: "form-control entry_field" %></li>
      </div>

      ...... # All of the other form fields

      <div class="field entry_box">
        <li><%= f.label "What budget do you have in mind?" %>
        <%= collection_select(:project, :budget_id, Budget.all, :id, :list_of_budgets, {include_blank: 'Please select'}, {class: "form-control entry_field"} ) %></li>
      </div>
    </ol>
    # No f.submit button -> moved to view
  </div>
<% end %>
  

новый вид.html.erb для новых проектов

 <div class="container">
  <div class="center">
    <h1>New Project</h1>
  </div>

  <%= form_for current_user do |f| %>
    <%= f.fields_for @project do |builder| %>
      <%= render 'form', :locals =>  { f: builder } %>
    <% end %>
    <div class="actions center space_big">
      <%= f.submit "Save Project", class: "btn btn-lg btn-success" %>
    </div>
  <% end %>
</div>
  
  1. Как мне заставить кнопку отправки в ее текущем положении работать?
  2. Что вызывает ошибку маршрутизации для uninitialized constant UsersController ?

Ответ №1:

В вашей _form части вам не нужна первая строка, т.е. form_for поскольку вы уже передали f , для form ('builder') которой является projects объект, поскольку вы создали его внутри fields_for @project блока.

итак, этого будет достаточно:

 <div class="project_form">
<ol>
  <div class="field entry_box">
    <li><%= f.label "Give your project a name" %>
    <%= f.text_field :name, placeholder: "A short name", class: "form-control entry_field" %></li>
  </div>

  ...... # All of the other form fields

  <div class="field entry_box">
    <li><%= f.label "What budget do you have in mind?" %>
    <%= collection_select(:project, :budget_id, Budget.all, :id, :list_of_budgets, {include_blank: 'Please select'}, {class: "form-control entry_field"} ) %></li>
  </div>
</ol>
# No f.submit button -> moved to view
</div>
  

и в вашей строке form_for current_user измените render на такую:

 <%= render partial: 'form', :locals =>  { f: builder } %>
  

и вы получаете это, controller error поскольку у вас этого нет UsersController , и вы создаете nested_form для User того current_user , что есть UsersController , поэтому у вас должен быть этот код внутри new build действия, а в нем — проект для пользователя.

Комментарии:

1. Спасибо. Я внес изменение, предложенное для _form , и я получаю ошибку для undefined local variable or method 'f' ссылки <li><%= f.label "What type of project is this?" %> ?

2. Извините за ясность, это одно из более ранних полей формы. Похоже, это не привязывает f из формы к f для полей

3. где у вас есть эта метка? потому что первая метка, которую я вижу, Give your project a name поэтому, если какая-либо ошибка, то она должна была быть вызвана этой меткой, поскольку она использует f первую

4. И возможное решение — использовать partial like render partial: 'form' . Я также обновляю ответ с помощью этой информации

5. Потрясающее спасибо, попробую это. Метка, которую вы видите, — это еще один похожий вопрос (у меня есть около 7 вопросов, но я удалил все остальные, чтобы упростить форму для этого поста). Но в основном, перетасовывая вопросы, он выдает ошибку для <li><%= f.label "Give your project a name" %>