rails 7、form_with & params: 2个值是如何在params[:modelname]之外的?
rails 7, form_with & params: How did 2 values get outside of the params[:modelname]?
我有一个场景,在管理员限制创建 'new' 邀请时,管理员无法输入其中的 2 个值。它们旨在稍后在用户 'registrars' 上设置。创建工作正常。
有问题的 2 个值是:responded 和:attending (RA)。 Responded 默认设置为 false,而 attending 没有设置,因此默认为 nil。
然后我有一个邀请的编辑页面,管理员可以在其中更新任何信息。我们的想法是,如果邀请犯了无法撤消的错误,那么管理员可以设置或重置为默认值。
编辑页面适用于所有值,但 RA 不会保存到数据库。它不会引发任何异常,并且在 invites_controller 的逻辑中继续进行,就好像它已被保存一样。
注意:我可以将这些更新并保存到值 w/out rails c
中的任何问题
我添加了一个 binding.break 来查看参数,我认为这是问题所在:
>params[:invite]
不包括 RA。但是如果我这样做 >params
我可以看到 ActionController::Parameters
的 'outside'
(rdbg) params
#<ActionController::Parameters
{"_method"=>"patch",
"authenticity_token"=>"keSUCTMDKkOYCVzCRKwaFuQN6EL9of-0SlyEIKEn6OHr_8766q23xh0LhcpU1GzPoM1xdr8XmGfuRQAmMw4gzg",
"invite"=>#<ActionController::Parameters
{
"username"=>"Jim",
"titulation"=>"Mr Jim",
"guest_count"=>"1",
"escort_count"=>"1",
"password"=>""
}
permitted: false>,
"attending"=>"true",
"responded"=>"true",
"commit"=>"Update Invite",
"controller"=>"invites",
"action"=>"update",
"id"=>"8"
} permitted: false>
(rdbg) params[:invite] # ruby
#<ActionController::Parameters
{
"username"=>"Jim",
"titulation"=>"Mr Jim",
"guest_count"=>"1",
"escort_count"=>"1",
"password"=>""
}
permitted: false>
(rdbg)
此处的架构部分:
create_table "invites", force: :cascade do |t|
t.string "username"
t.string "titulation"
t.integer "guest_count"
t.integer "escort_count"
t.boolean "responded"
t.boolean "attending"
t.string "password"
t.string "password_digest"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
invite.rb(型号)
class Invite < ApplicationRecord
validates :username, presence: true, uniqueness: { case_sensitive: false }, length: { minimum: 3, maximum: 25 }
has_secure_password
attribute :responded, default: false
end
invite_controller.rb:
注意:因为 'new' 页面不允许管理员设置 RA 值,所以我有 invite_params 用于创建,invite_extended_params 用于更新
...
定义新
如果 logged_in_admin?
@邀请= Invite.new
别的
flash[:notice] = "只有管理员可以访问该页面。"
redirect_to root_path
结尾
结束
def create
@invite = Invite.new(invite_params) # does not include responded & attending
if @invite.save
flash[:notice] = "Created new invite for #{@invite.titulation}"
redirect_to invite_path(@invite.id)
end
end
def show
@invite = Invite.find(params[:id])
end
def edit
@invite = Invite.find(params[:id])
if @invite.responded
flash.now[:alert] = "Warning, this invite has responded. Make sure you know what you're doing."
end
end
def update
@invite = Invite.find(params[:id])
if @invite.update(invite_extended_params) # includes responded & attending
binding.break
flash[:notice] = "Update was saved."
redirect_to invite_path(@invite.id)
else
flash.now[:alert] = "Something went wrong"
render 'edit'
end
end
private
def invite_params
params.require(:invite).permit(:username, :titulation, :guest_count, :escort_count, :password)
end
def invite_extended_params
params.require(:invite).permit(:username, :titulation, :guest_count, :escort_count, :password, :responded, :attending)
end
end
编辑页面代码:
<%= form_with(model: @invite, class: "shadow p-3 mb-3 bg-info rounded", local: true) do |form| %>
<div class="form-group row">
<%= form.label :username, class: "col-2 col-form-label text-light" %>
<div class="col-10">
<%= form.text_field :username, class: "form-control shadow rounded", placeholder: "Enter Unique username" %>
</div>
</div>
<div class="form-group row">
<%= form.label :titulation, class: "col-2 col-form-label text-light" %>
<div class="col-10">
<%= form.text_field :titulation, class: "form-control shadow rounded", placeholder: "Enter Titulation" %>
</div>
</div>
<div class="form-group row">
<%= form.label :guest_count, class: "col-2 col-form-label text-light" %>
<div class="col-10">
<%= form.number_field :guest_count, class: "form-control shadow rounded", placeholder: "How many Guests for this invite?" %>
</div>
</div>
<div class="form-group row">
<%= form.label :escort_count, class: "col-2 col-form-label text-light" %>
<div class="col-10">
<%= form.number_field :escort_count, class: "form-control shadow rounded", placeholder: "How many +1's for this invite?" %>
</div>
</div>
<div class="form-group row">
<%= form.label :password, class: "col-2 col-form-label text-light" %>
<div class="col-10">
<%= form.text_field :password, class: "form-control shadow rounded", placeholder: "Preset password" %>
</div>
</div>
<div class="form-group row">
<div class="col-2 col-form-label text-light"> Attendance:
<div class="col-10">
<%= radio_button_tag(:attending, true) %>
<%= label_tag(:attending, "Yes") %>
<%= radio_button_tag(:attending, false) %>
<%= label_tag(:attending, "No") %>
</div>
</div>
<div class="form-group row">
<div class="col-2 col-form-label text-light"> Responded:
<div class="col-10">
<%= radio_button_tag(:responded, true, @invite.responded) %>
<%= label_tag(:responded, "Yes") %>
<%= radio_button_tag(:responded, false, !@invite.responded) %>
<%= label_tag(:responded, "No") %>
</div>
</div>
<%= form.submit 'Update Invite' %>
<% end %>
单选按钮作为没有表单上下文的标签添加到 html,因此它们不包含在表单的邀请参数中。
要修复更改它们以使用 form.radio_button
。例如,更改 ...
<%= radio_button_tag(:attending, true) %>
至
<%= form.radio_button(:attending, true) %>
我有一个场景,在管理员限制创建 'new' 邀请时,管理员无法输入其中的 2 个值。它们旨在稍后在用户 'registrars' 上设置。创建工作正常。
有问题的 2 个值是:responded 和:attending (RA)。 Responded 默认设置为 false,而 attending 没有设置,因此默认为 nil。
然后我有一个邀请的编辑页面,管理员可以在其中更新任何信息。我们的想法是,如果邀请犯了无法撤消的错误,那么管理员可以设置或重置为默认值。
编辑页面适用于所有值,但 RA 不会保存到数据库。它不会引发任何异常,并且在 invites_controller 的逻辑中继续进行,就好像它已被保存一样。
注意:我可以将这些更新并保存到值 w/out rails c
中的任何问题我添加了一个 binding.break 来查看参数,我认为这是问题所在:
>params[:invite]
不包括 RA。但是如果我这样做 >params
我可以看到 ActionController::Parameters
(rdbg) params
#<ActionController::Parameters
{"_method"=>"patch",
"authenticity_token"=>"keSUCTMDKkOYCVzCRKwaFuQN6EL9of-0SlyEIKEn6OHr_8766q23xh0LhcpU1GzPoM1xdr8XmGfuRQAmMw4gzg",
"invite"=>#<ActionController::Parameters
{
"username"=>"Jim",
"titulation"=>"Mr Jim",
"guest_count"=>"1",
"escort_count"=>"1",
"password"=>""
}
permitted: false>,
"attending"=>"true",
"responded"=>"true",
"commit"=>"Update Invite",
"controller"=>"invites",
"action"=>"update",
"id"=>"8"
} permitted: false>
(rdbg) params[:invite] # ruby
#<ActionController::Parameters
{
"username"=>"Jim",
"titulation"=>"Mr Jim",
"guest_count"=>"1",
"escort_count"=>"1",
"password"=>""
}
permitted: false>
(rdbg)
此处的架构部分:
create_table "invites", force: :cascade do |t|
t.string "username"
t.string "titulation"
t.integer "guest_count"
t.integer "escort_count"
t.boolean "responded"
t.boolean "attending"
t.string "password"
t.string "password_digest"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
invite.rb(型号)
class Invite < ApplicationRecord
validates :username, presence: true, uniqueness: { case_sensitive: false }, length: { minimum: 3, maximum: 25 }
has_secure_password
attribute :responded, default: false
end
invite_controller.rb:
注意:因为 'new' 页面不允许管理员设置 RA 值,所以我有 invite_params 用于创建,invite_extended_params 用于更新 ... 定义新 如果 logged_in_admin? @邀请= Invite.new 别的 flash[:notice] = "只有管理员可以访问该页面。" redirect_to root_path 结尾 结束
def create
@invite = Invite.new(invite_params) # does not include responded & attending
if @invite.save
flash[:notice] = "Created new invite for #{@invite.titulation}"
redirect_to invite_path(@invite.id)
end
end
def show
@invite = Invite.find(params[:id])
end
def edit
@invite = Invite.find(params[:id])
if @invite.responded
flash.now[:alert] = "Warning, this invite has responded. Make sure you know what you're doing."
end
end
def update
@invite = Invite.find(params[:id])
if @invite.update(invite_extended_params) # includes responded & attending
binding.break
flash[:notice] = "Update was saved."
redirect_to invite_path(@invite.id)
else
flash.now[:alert] = "Something went wrong"
render 'edit'
end
end
private
def invite_params
params.require(:invite).permit(:username, :titulation, :guest_count, :escort_count, :password)
end
def invite_extended_params
params.require(:invite).permit(:username, :titulation, :guest_count, :escort_count, :password, :responded, :attending)
end
end
编辑页面代码:
<%= form_with(model: @invite, class: "shadow p-3 mb-3 bg-info rounded", local: true) do |form| %>
<div class="form-group row">
<%= form.label :username, class: "col-2 col-form-label text-light" %>
<div class="col-10">
<%= form.text_field :username, class: "form-control shadow rounded", placeholder: "Enter Unique username" %>
</div>
</div>
<div class="form-group row">
<%= form.label :titulation, class: "col-2 col-form-label text-light" %>
<div class="col-10">
<%= form.text_field :titulation, class: "form-control shadow rounded", placeholder: "Enter Titulation" %>
</div>
</div>
<div class="form-group row">
<%= form.label :guest_count, class: "col-2 col-form-label text-light" %>
<div class="col-10">
<%= form.number_field :guest_count, class: "form-control shadow rounded", placeholder: "How many Guests for this invite?" %>
</div>
</div>
<div class="form-group row">
<%= form.label :escort_count, class: "col-2 col-form-label text-light" %>
<div class="col-10">
<%= form.number_field :escort_count, class: "form-control shadow rounded", placeholder: "How many +1's for this invite?" %>
</div>
</div>
<div class="form-group row">
<%= form.label :password, class: "col-2 col-form-label text-light" %>
<div class="col-10">
<%= form.text_field :password, class: "form-control shadow rounded", placeholder: "Preset password" %>
</div>
</div>
<div class="form-group row">
<div class="col-2 col-form-label text-light"> Attendance:
<div class="col-10">
<%= radio_button_tag(:attending, true) %>
<%= label_tag(:attending, "Yes") %>
<%= radio_button_tag(:attending, false) %>
<%= label_tag(:attending, "No") %>
</div>
</div>
<div class="form-group row">
<div class="col-2 col-form-label text-light"> Responded:
<div class="col-10">
<%= radio_button_tag(:responded, true, @invite.responded) %>
<%= label_tag(:responded, "Yes") %>
<%= radio_button_tag(:responded, false, !@invite.responded) %>
<%= label_tag(:responded, "No") %>
</div>
</div>
<%= form.submit 'Update Invite' %>
<% end %>
单选按钮作为没有表单上下文的标签添加到 html,因此它们不包含在表单的邀请参数中。
要修复更改它们以使用 form.radio_button
。例如,更改 ...
<%= radio_button_tag(:attending, true) %>
至
<%= form.radio_button(:attending, true) %>