形成关联:控制器同时将信息保存到 2 个模型时遇到问题
Form associations: Having trouble with controller saving information to 2 models simultaneously
对于我的项目,我正在尝试构建一个仪表板,代理可以在其中查看用户发布的提交并为每个提交添加状态和注释以记录他们自己的个人 activity 即他们不会正在更改实际记录,只是留下私人笔记反对它。为此,我创建了一个包含代理 ID 和提交 ID 以及状态和注释列的连接 table。
我已经成功地创建了一个索引视图,该视图显示提交数据,在我的连接 table 的每行末尾有 2 个表单字段,它们被称为状态和注释...问题是当我更新时这些字段不会保存到我的连接table.
索引视图上的表单
<%= form_with(model: submission, local: true) do |form| %>
<% form.fields_for :agent_activities do |act| %>
<td> <div class="field">
<%= act.text_field :Status %>
</div>
</td>
<td> <div class="field">
<%= act.text_field :Notes %>
</div>
</td>
<td>
<div class="actions">
<%= form.submit %>
</div>
</td>
<% end %>
<% end %>
rb 文件中的模型关联
class Submission < ApplicationRecord
belongs_to :user, :optional => true
belongs_to :location, :optional => true
has_many :agent_activities
end
class AgentActivity < ApplicationRecord
belongs_to :submission, :optional => true #has submission_id
foreign key in table
belongs_to :agent, :optional => true #has agent_id foreign key in
table
end
控制器:
class SubmissionsController < ApplicationController
before_action :set_submission, only: [:show, :edit, :update, :destroy]
def index
@submissions = Submission.where(:user_id => current_user.id)
end
def show
end
def new
@submission = Submission.new
end
def edit
end
# POST /submissions
# POST /submissions.json
def create
@submission = Submission.new(submission_params.merge(user_id: current_user.id))
respond_to do |format|
if @submission.save
# Tell the UserMailer to send a welcome email after save
NewSubmissionMailer.submission_email(@submission).deliver_now
NewSubmissionMailer.matching_agents_email(@submission).deliver_now
format.html { redirect_to @submission, notice: 'Submission was successfully created.' }
format.json { render :show, status: :created, location: @submission }
else
format.html { render :new }
format.json { render json: @submission.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /submissions/1
# PATCH/PUT /submissions/1.json
def update
respond_to do |format|
if @submission.update(submission_params)
format.html { redirect_to @submission, notice: 'Submission was successfully updated.' }
format.json { render :show, status: :ok, location: @submission }
else
format.html { render :edit }
format.json { render json: @submission.errors, status: :unprocessable_entity }
end
end
end
# DELETE /submissions/1
# DELETE /submissions/1.json
def destroy
@submission.destroy
respond_to do |format|
format.html { redirect_to submissions_url, notice: 'Submission was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_submission
@submission = Submission.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def submission_params
params.require(:submission).permit(:First_Name, :Last_Name, :Phone, :Email, :Desired_Location, :number_of_beds, :number_of_occupants, :Rent_price_per_month_gbp, :Max_move_in_date, :Tenant_Occupation, :Contact_me_on, :Furnished, :Current_Address, :Property_Requirements)
end
end
不确定我在这里遗漏了什么:/
更新基于@TOM 回答
新控制器参数:
def submission_params
params.require(:submission).permit(:First_Name, :Last_Name, :Phone, :Email, :Desired_Location, :number_of_beds, :number_of_occupants, :Rent_price_per_month_gbp, :Max_move_in_date, :Tenant_Occupation, :Contact_me_on, :Furnished, :Current_Address, :Property_Requirements, agent_activities_attributes: [:id, :Status, :Notes, :_destroy])
end
结束
新提交模型 rb:
class Submission < ApplicationRecord
belongs_to :user, :optional => true
belongs_to :location, :optional => true
has_many :agent_activities
accepts_nested_attributes_for :agent_activities
end
Index.html.erb
<%= form_with(model: submission, local: true) do |form| %>
<% form.fields_for :agent_activities, @submission.agent_activities.build do |act| %>
<td> <div class="field">
<%= act.text_field :Status %>
</div>
</td>
<td> <div class="field">
<%= act.text_field :Notes %>
</div>
</td>
<td>
<div class="actions">
<%= form.submit %>
</div>
</td>
<% end %>
在您的 Submission
模型上添加:accepts_nested_attributes_for :agent_activities
(accepts_nested_attributes_for documentation) 这会让 Rails 知道您的表单将提供字段对于关联模型。
添加后 Rails 将在您的强参数中提供参数 agent_activities_attributes
中的键,我们可以添加:.permit(..., agent_activities_attributes: [:id, :Status, :Notes, :_destroy]
。仅当您计划在嵌套属性调用中使用 allow_destroy: true
时才需要 :_destroy
键。
附带说明:大写名称(Status
、Notes
等)通常保留用于 Ruby 中的常量。您可能需要考虑将属性列名称更改为小写。
对于我的项目,我正在尝试构建一个仪表板,代理可以在其中查看用户发布的提交并为每个提交添加状态和注释以记录他们自己的个人 activity 即他们不会正在更改实际记录,只是留下私人笔记反对它。为此,我创建了一个包含代理 ID 和提交 ID 以及状态和注释列的连接 table。
我已经成功地创建了一个索引视图,该视图显示提交数据,在我的连接 table 的每行末尾有 2 个表单字段,它们被称为状态和注释...问题是当我更新时这些字段不会保存到我的连接table.
索引视图上的表单
<%= form_with(model: submission, local: true) do |form| %>
<% form.fields_for :agent_activities do |act| %>
<td> <div class="field">
<%= act.text_field :Status %>
</div>
</td>
<td> <div class="field">
<%= act.text_field :Notes %>
</div>
</td>
<td>
<div class="actions">
<%= form.submit %>
</div>
</td>
<% end %>
<% end %>
rb 文件中的模型关联
class Submission < ApplicationRecord
belongs_to :user, :optional => true
belongs_to :location, :optional => true
has_many :agent_activities
end
class AgentActivity < ApplicationRecord
belongs_to :submission, :optional => true #has submission_id
foreign key in table
belongs_to :agent, :optional => true #has agent_id foreign key in
table
end
控制器:
class SubmissionsController < ApplicationController
before_action :set_submission, only: [:show, :edit, :update, :destroy]
def index
@submissions = Submission.where(:user_id => current_user.id)
end
def show
end
def new
@submission = Submission.new
end
def edit
end
# POST /submissions
# POST /submissions.json
def create
@submission = Submission.new(submission_params.merge(user_id: current_user.id))
respond_to do |format|
if @submission.save
# Tell the UserMailer to send a welcome email after save
NewSubmissionMailer.submission_email(@submission).deliver_now
NewSubmissionMailer.matching_agents_email(@submission).deliver_now
format.html { redirect_to @submission, notice: 'Submission was successfully created.' }
format.json { render :show, status: :created, location: @submission }
else
format.html { render :new }
format.json { render json: @submission.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /submissions/1
# PATCH/PUT /submissions/1.json
def update
respond_to do |format|
if @submission.update(submission_params)
format.html { redirect_to @submission, notice: 'Submission was successfully updated.' }
format.json { render :show, status: :ok, location: @submission }
else
format.html { render :edit }
format.json { render json: @submission.errors, status: :unprocessable_entity }
end
end
end
# DELETE /submissions/1
# DELETE /submissions/1.json
def destroy
@submission.destroy
respond_to do |format|
format.html { redirect_to submissions_url, notice: 'Submission was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_submission
@submission = Submission.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def submission_params
params.require(:submission).permit(:First_Name, :Last_Name, :Phone, :Email, :Desired_Location, :number_of_beds, :number_of_occupants, :Rent_price_per_month_gbp, :Max_move_in_date, :Tenant_Occupation, :Contact_me_on, :Furnished, :Current_Address, :Property_Requirements)
end
end
不确定我在这里遗漏了什么:/
更新基于@TOM 回答
新控制器参数:
def submission_params
params.require(:submission).permit(:First_Name, :Last_Name, :Phone, :Email, :Desired_Location, :number_of_beds, :number_of_occupants, :Rent_price_per_month_gbp, :Max_move_in_date, :Tenant_Occupation, :Contact_me_on, :Furnished, :Current_Address, :Property_Requirements, agent_activities_attributes: [:id, :Status, :Notes, :_destroy])
end
结束
新提交模型 rb:
class Submission < ApplicationRecord
belongs_to :user, :optional => true
belongs_to :location, :optional => true
has_many :agent_activities
accepts_nested_attributes_for :agent_activities
end
Index.html.erb
<%= form_with(model: submission, local: true) do |form| %>
<% form.fields_for :agent_activities, @submission.agent_activities.build do |act| %>
<td> <div class="field">
<%= act.text_field :Status %>
</div>
</td>
<td> <div class="field">
<%= act.text_field :Notes %>
</div>
</td>
<td>
<div class="actions">
<%= form.submit %>
</div>
</td>
<% end %>
在您的
Submission
模型上添加:accepts_nested_attributes_for :agent_activities
(accepts_nested_attributes_for documentation) 这会让 Rails 知道您的表单将提供字段对于关联模型。添加后 Rails 将在您的强参数中提供参数
agent_activities_attributes
中的键,我们可以添加:.permit(..., agent_activities_attributes: [:id, :Status, :Notes, :_destroy]
。仅当您计划在嵌套属性调用中使用allow_destroy: true
时才需要:_destroy
键。
附带说明:大写名称(Status
、Notes
等)通常保留用于 Ruby 中的常量。您可能需要考虑将属性列名称更改为小写。