Rails 嵌套属性形式:创建具有多对多关系的对象时出错
Rails nested attribute form: error when creating an object with a many-to-many relationship
我的项目在以下 class 之间存在多对多关系:
class Project < ApplicationRecord
has_many :project_software_processes, inverse_of: :project, :dependent => :delete_all
has_many :software_processes, through: :project_software_processes
accepts_nested_attributes_for :project_software_processes
attr_accessor :project_attributes
end
..
class SoftwareProcess < ApplicationRecord
has_many :project_software_processes
has_many :projects, through: :project_software_processes
end
--
class ProjectSoftwareProcess < ApplicationRecord
belongs_to :software_process
belongs_to :project
end
- -
我正在使用嵌套表单创建项目实例,以便用户可以根据需要选择任意数量的软件进程:
<div class="field">
<%= f.label :software_processes %>
<%= f.fields_for :project_software_processes do |project_software_process| %>
<%= project_software_process.select(:software_processes_id, @processes.collect { |s| [s.name, s.id] } ) %>
<%= project_software_process.link_to_remove "Remove this SoftwareProcess" %>
<% end %>
<p><%= f.link_to_add "Add a process", :project_software_processes %></p>
</div>
问题是,当我点击提交时,我收到以下验证消息:
Project software processes software process must exist
我花了一点时间才明白错误的真正含义。我猜它在尝试创建 project software process
的实例时抱怨 software process
class 的存在。但是,有项目软件过程的实例,用户甚至可以在select下拉列表中select它们。不确定这是否是问题所在。
这是我的项目控制器的一些片段:
def create
@project = Project.new(project_params)
@project.user = current_user
respond_to do |format|
if @project.save
format.html { redirect_to @project, notice: 'Project was successfully created.' }
format.json { render :show, status: :created, location: @project }
else
@processes = SoftwareProcess.all
format.html { render :new }
format.json { render json: @project.errors, status: :unprocessable_entity }
end
end
end
--
def project_params
params.require(:project).permit(:name, :user_id, project_software_processes_attributes: [:software_process_id, :_destroy])
end
--
这是在参数中发送的内容:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"[FILTERED]", "project"=>{"name"=>"aas", "project_software_processes_attributes"=>{"1484020859023"=>{"software_processes_id"=>"1", "_destroy"=>"false"}, "1484020859693"=>{"software_processes_id"=>"4", "_destroy"=>"false"}}}, "commit"=>"Create Project"}
问题出在 select
方法的名称上,应该是 software_process_id
而不是 software_processes_id
。尝试将其更改为:
<%= project_software_process.select(:software_process_id, @processes.collect { |s| [s.name, s.id] } ) %>
此外,Ryan Bate 的软件现在已经相当过时了,nested_forms gem 也不例外。我见过有人推荐 Cocoon 作为合适的替代品。看看here
干杯。
我的项目在以下 class 之间存在多对多关系:
class Project < ApplicationRecord
has_many :project_software_processes, inverse_of: :project, :dependent => :delete_all
has_many :software_processes, through: :project_software_processes
accepts_nested_attributes_for :project_software_processes
attr_accessor :project_attributes
end
..
class SoftwareProcess < ApplicationRecord
has_many :project_software_processes
has_many :projects, through: :project_software_processes
end
--
class ProjectSoftwareProcess < ApplicationRecord
belongs_to :software_process
belongs_to :project
end
- -
我正在使用嵌套表单创建项目实例,以便用户可以根据需要选择任意数量的软件进程:
<div class="field">
<%= f.label :software_processes %>
<%= f.fields_for :project_software_processes do |project_software_process| %>
<%= project_software_process.select(:software_processes_id, @processes.collect { |s| [s.name, s.id] } ) %>
<%= project_software_process.link_to_remove "Remove this SoftwareProcess" %>
<% end %>
<p><%= f.link_to_add "Add a process", :project_software_processes %></p>
</div>
问题是,当我点击提交时,我收到以下验证消息:
Project software processes software process must exist
我花了一点时间才明白错误的真正含义。我猜它在尝试创建 project software process
的实例时抱怨 software process
class 的存在。但是,有项目软件过程的实例,用户甚至可以在select下拉列表中select它们。不确定这是否是问题所在。
这是我的项目控制器的一些片段:
def create
@project = Project.new(project_params)
@project.user = current_user
respond_to do |format|
if @project.save
format.html { redirect_to @project, notice: 'Project was successfully created.' }
format.json { render :show, status: :created, location: @project }
else
@processes = SoftwareProcess.all
format.html { render :new }
format.json { render json: @project.errors, status: :unprocessable_entity }
end
end
end
--
def project_params
params.require(:project).permit(:name, :user_id, project_software_processes_attributes: [:software_process_id, :_destroy])
end
--
这是在参数中发送的内容:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"[FILTERED]", "project"=>{"name"=>"aas", "project_software_processes_attributes"=>{"1484020859023"=>{"software_processes_id"=>"1", "_destroy"=>"false"}, "1484020859693"=>{"software_processes_id"=>"4", "_destroy"=>"false"}}}, "commit"=>"Create Project"}
问题出在 select
方法的名称上,应该是 software_process_id
而不是 software_processes_id
。尝试将其更改为:
<%= project_software_process.select(:software_process_id, @processes.collect { |s| [s.name, s.id] } ) %>
此外,Ryan Bate 的软件现在已经相当过时了,nested_forms gem 也不例外。我见过有人推荐 Cocoon 作为合适的替代品。看看here
干杯。