Rails DRY 多个视图的嵌套表单
Rails DRY nested forms for multiple views
我正在尝试创建一个 DRY 表单,我可以将其用作 form_fields 用于不同视图中的其他嵌套表单。我有 2 个问题。
- 我希望
_form
部分没有提交按钮,而是在表单本身上有此按钮。但是,单击当前位置的提交按钮没有任何作用??
- 表单在当前状态下显示良好。如果我将提交按钮移动到
_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)(?=.*[\@\#$\%\^\&\+\=]).*\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 %>
new.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>
- 如何使当前位置的提交按钮起作用?
- 是什么导致了
uninitialized constant UsersController
的路由错误?
在您的 _form
部分中,您不需要第一行,即 form_for
,因为您已经通过了 f
,这是 projects
的 form ('builder')
对象因为你在 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
并且你正在为 User
制作 nested_form
即 current_user
所以你应该在 UsersController
的 new
操作和 build
那里的用户项目中包含此代码。
我正在尝试创建一个 DRY 表单,我可以将其用作 form_fields 用于不同视图中的其他嵌套表单。我有 2 个问题。
- 我希望
_form
部分没有提交按钮,而是在表单本身上有此按钮。但是,单击当前位置的提交按钮没有任何作用?? - 表单在当前状态下显示良好。如果我将提交按钮移动到
_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)(?=.*[\@\#$\%\^\&\+\=]).*\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 %>
new.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>
- 如何使当前位置的提交按钮起作用?
- 是什么导致了
uninitialized constant UsersController
的路由错误?
在您的 _form
部分中,您不需要第一行,即 form_for
,因为您已经通过了 f
,这是 projects
的 form ('builder')
对象因为你在 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
并且你正在为 User
制作 nested_form
即 current_user
所以你应该在 UsersController
的 new
操作和 build
那里的用户项目中包含此代码。