为什么我的 Rails hidden_field 在所有其他字段都正常工作时没有获取任何值?
Why is my Rails hidden_field not picking up any value when all other fields work fine?
我有一个 "timeline_event" 模型,其中 belongs_to 一个 sales_opportunity。例如,它可以是 "call the prospect" 或类似的,带有 due_date、activity_details(可选)和一个复选框来说明它是否完整。这很好用。我可以通过 sales_opportunity 页面上的模式向数据库添加新的 timeline_events,这也可以正常工作。但是,当我尝试编辑 timeline_event(通过 timeline_events 编辑控制器操作)时,sales_opportunity_id 的 hidden_field 拒绝获取值(它没有任何价值) .即使我试图强制一个值:
<%= f.hidden_field :sales_opportunity_id, :value => @sales_opportunity.id %>
它不会为 hidden_field 添加任何值。我试过在表单组中移动字段,但似乎没有任何效果。我有其他与我的模型相似的表格,它们工作正常,但由于某种原因,这不起作用 - 谁能帮忙吗?
我的表格:
<%= form_for(@timeline_event, :html => {:class => "form-horizontal"}) do |f| %>
<div class="form-group">
<%= f.hidden_field :sales_opportunity_id %>
<%= f.label :activity, :class => "col-md-4 control-label" %>
<div class ="col-md-8">
<%= f.text_field :activity, :placeholder => "Enter activity details" %>
</div>
</div>
<div class="form-group">
<%= f.label :due_date, :class => "col-md-4 control-label" %>
<div class ="col-md-8">
<div class='input-group date' id='datetimepicker' data-date-format="YY.MM.DD">
<%= f.text_field :due_date, class: "form-control", data: { date_format: 'YYYY/MM/DD' }, :placeholder => "YYYY/MM/DD" %>
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
</div>
<div class="form-group">
<%= f.label :event_notes, 'Activity Details', :class => "col-md-4 control-label" %>
<div class ="col-md-8">
<%= f.text_area(:event_notes, :placeholder => "Put any notes about the activity here") %>
</div>
</div>
<div class="col-md-6 col-md-offset-4">
<div class="checkbox input">
<label>
<%= f.check_box :completed %> Task Completed?
</label>
</div>
<br>
</div>
<%= @sales_opportunity.id %>
<%= f.submit "Save", class: "btn btn-large btn-success" %>
<% end %>
*注意 - 我在此处包含 <%= @sales_opportunity.id %> 行,这确实为 timeline_event 输出了正确的 sales_opportunity_id。所有其他字段(活动、due_date、已完成)都填充了我正在尝试编辑的 timeline_event 的信息。
Timeline_Events_Controller:
class TimelineEventsController < ApplicationController
before_action :set_timeline_event, only: [:show, :edit, :update, :destroy]
before_action :signed_in_user, only: [:edit, :update, :show, :index]
before_action :correct_org, only: [:edit, :update, :show, :index]
# GET /timeline_events
# GET /timeline_events.json
def index
@timeline_events = TimelineEvent.all
end
# GET /timeline_events/1
# GET /timeline_events/1.json
def show
end
# GET /timeline_events/new
def new
@timeline_event = TimelineEvent.new(sales_opportunity_id: params[:sales_opportunity_id])
end
# GET /timeline_events/1/edit
def edit
@timeline_event = TimelineEvent.find(params[:id])
@sales_opportunity = @timeline_event.sales_opportunity
end
# POST /timeline_events
# POST /timeline_events.json
def create
@timeline_event = TimelineEvent.new(timeline_event_params)
@sales_opportunity = @timeline_event.sales_opportunity
respond_to do |format|
if @timeline_event.save
format.html { redirect_to @timeline_event.sales_opportunity, :flash => {:success => 'Timeline event was successfully created.'} }
format.json { render :show, status: :created, location: @timeline_event }
format.js
else
format.html { render :new }
format.json { render json: @timeline_event.errors, status: :unprocessable_entity }
format.js { render json: @sales_opportunity.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /timeline_events/1
# PATCH/PUT /timeline_events/1.json
def update
respond_to do |format|
if @timeline_event.update(timeline_event_params)
format.html { redirect_to @timeline_event.sales_opportunity, :flash => {:success => 'Timeline event was successfully updated.'} }
format.json { render :show, status: :ok, location: @timeline_event }
else
format.html { render :edit }
format.json { render json: @timeline_event.errors, status: :unprocessable_entity }
end
end
end
# DELETE /timeline_events/1
# DELETE /timeline_events/1.json
def destroy
@timeline_event.destroy
respond_to do |format|
format.html { redirect_to timeline_events_url, :flash => {:success => 'Timeline event was successfully destroyed.'} }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_timeline_event
@timeline_event = TimelineEvent.find(params[:id])
end
def timeline_event_params
params.require(:timeline_event).permit(:sales_opportunity_id, :due_date, :activity, :completed, :event_notes)
end
#before filters
def signed_in_user
unless signed_in?
store_location
redirect_to signin_url, notice: "Please sign in." unless signed_in?
end
end
def correct_org
timeline_org = @timeline_event.sales_opportunity.user.organization
@user = current_user
if @user.organization_id == timeline_org.id
else
redirect_to root_url, notice: "You are not permitted to visit that page. Please create an account or sign in"
end
end
end
我的timeline_event模特:
class TimelineEvent < ActiveRecord::Base
belongs_to :sales_opportunity
validates :activity, presence: true
validates :due_date, presence: true
validates :sales_opportunity_id, presence: true
end
我只能想象这是我的一些语法错误或其他愚蠢的错误,因为我看不出代码有任何问题(它与我网站上的所有其他表单相同)。请问有人能指出我哪里出错了吗?
谢谢!
form_for
字段助手不是那样工作的,他们不会在选项中使用 :value
键。基本上字段的名称 必须 对应于您传递给 form_for
的对象的方法(在您的情况下 @timeline_event
),这就是表单的位置将从中获取值。
如果您想提供自己的字段和值,请使用 _tag
帮手系列,例如:
<%= hidden_field_tag :name_of_field, @sales_opportunity.id %>
或使用f.fields_for
创建子字段(通常结合accepts_nested_attributes_for
)
我不同意@smathy,因为您确实可以像您所做的那样将值显式传递给hidden_field
标记。
但是,这甚至没有必要,因为您正在进行循环分配。我的意思是您在控制器的 edit
操作中声明 @sales_opportunity
并为其分配 @timeline_event.sales_opportunity
的值。
然后您进入视图并尝试将 @timeline_event.sales_opportunity
分配回 @sales_opportunity
。这就是循环逻辑。
如果您正在编辑的 timeline_event
的 sales_opportunity
已经存在,并且您不想让用户对其进行编辑,那么为什么要将其包含在表单中呢?从控制器中的 edit
操作中删除 @sales_opportunity
实例变量,并从视图中完全删除隐藏字段。
看看这样做是否能按预期工作。
我有一个 "timeline_event" 模型,其中 belongs_to 一个 sales_opportunity。例如,它可以是 "call the prospect" 或类似的,带有 due_date、activity_details(可选)和一个复选框来说明它是否完整。这很好用。我可以通过 sales_opportunity 页面上的模式向数据库添加新的 timeline_events,这也可以正常工作。但是,当我尝试编辑 timeline_event(通过 timeline_events 编辑控制器操作)时,sales_opportunity_id 的 hidden_field 拒绝获取值(它没有任何价值) .即使我试图强制一个值:
<%= f.hidden_field :sales_opportunity_id, :value => @sales_opportunity.id %>
它不会为 hidden_field 添加任何值。我试过在表单组中移动字段,但似乎没有任何效果。我有其他与我的模型相似的表格,它们工作正常,但由于某种原因,这不起作用 - 谁能帮忙吗?
我的表格:
<%= form_for(@timeline_event, :html => {:class => "form-horizontal"}) do |f| %>
<div class="form-group">
<%= f.hidden_field :sales_opportunity_id %>
<%= f.label :activity, :class => "col-md-4 control-label" %>
<div class ="col-md-8">
<%= f.text_field :activity, :placeholder => "Enter activity details" %>
</div>
</div>
<div class="form-group">
<%= f.label :due_date, :class => "col-md-4 control-label" %>
<div class ="col-md-8">
<div class='input-group date' id='datetimepicker' data-date-format="YY.MM.DD">
<%= f.text_field :due_date, class: "form-control", data: { date_format: 'YYYY/MM/DD' }, :placeholder => "YYYY/MM/DD" %>
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
</div>
<div class="form-group">
<%= f.label :event_notes, 'Activity Details', :class => "col-md-4 control-label" %>
<div class ="col-md-8">
<%= f.text_area(:event_notes, :placeholder => "Put any notes about the activity here") %>
</div>
</div>
<div class="col-md-6 col-md-offset-4">
<div class="checkbox input">
<label>
<%= f.check_box :completed %> Task Completed?
</label>
</div>
<br>
</div>
<%= @sales_opportunity.id %>
<%= f.submit "Save", class: "btn btn-large btn-success" %>
<% end %>
*注意 - 我在此处包含 <%= @sales_opportunity.id %> 行,这确实为 timeline_event 输出了正确的 sales_opportunity_id。所有其他字段(活动、due_date、已完成)都填充了我正在尝试编辑的 timeline_event 的信息。
Timeline_Events_Controller:
class TimelineEventsController < ApplicationController
before_action :set_timeline_event, only: [:show, :edit, :update, :destroy]
before_action :signed_in_user, only: [:edit, :update, :show, :index]
before_action :correct_org, only: [:edit, :update, :show, :index]
# GET /timeline_events
# GET /timeline_events.json
def index
@timeline_events = TimelineEvent.all
end
# GET /timeline_events/1
# GET /timeline_events/1.json
def show
end
# GET /timeline_events/new
def new
@timeline_event = TimelineEvent.new(sales_opportunity_id: params[:sales_opportunity_id])
end
# GET /timeline_events/1/edit
def edit
@timeline_event = TimelineEvent.find(params[:id])
@sales_opportunity = @timeline_event.sales_opportunity
end
# POST /timeline_events
# POST /timeline_events.json
def create
@timeline_event = TimelineEvent.new(timeline_event_params)
@sales_opportunity = @timeline_event.sales_opportunity
respond_to do |format|
if @timeline_event.save
format.html { redirect_to @timeline_event.sales_opportunity, :flash => {:success => 'Timeline event was successfully created.'} }
format.json { render :show, status: :created, location: @timeline_event }
format.js
else
format.html { render :new }
format.json { render json: @timeline_event.errors, status: :unprocessable_entity }
format.js { render json: @sales_opportunity.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /timeline_events/1
# PATCH/PUT /timeline_events/1.json
def update
respond_to do |format|
if @timeline_event.update(timeline_event_params)
format.html { redirect_to @timeline_event.sales_opportunity, :flash => {:success => 'Timeline event was successfully updated.'} }
format.json { render :show, status: :ok, location: @timeline_event }
else
format.html { render :edit }
format.json { render json: @timeline_event.errors, status: :unprocessable_entity }
end
end
end
# DELETE /timeline_events/1
# DELETE /timeline_events/1.json
def destroy
@timeline_event.destroy
respond_to do |format|
format.html { redirect_to timeline_events_url, :flash => {:success => 'Timeline event was successfully destroyed.'} }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_timeline_event
@timeline_event = TimelineEvent.find(params[:id])
end
def timeline_event_params
params.require(:timeline_event).permit(:sales_opportunity_id, :due_date, :activity, :completed, :event_notes)
end
#before filters
def signed_in_user
unless signed_in?
store_location
redirect_to signin_url, notice: "Please sign in." unless signed_in?
end
end
def correct_org
timeline_org = @timeline_event.sales_opportunity.user.organization
@user = current_user
if @user.organization_id == timeline_org.id
else
redirect_to root_url, notice: "You are not permitted to visit that page. Please create an account or sign in"
end
end
end
我的timeline_event模特:
class TimelineEvent < ActiveRecord::Base
belongs_to :sales_opportunity
validates :activity, presence: true
validates :due_date, presence: true
validates :sales_opportunity_id, presence: true
end
我只能想象这是我的一些语法错误或其他愚蠢的错误,因为我看不出代码有任何问题(它与我网站上的所有其他表单相同)。请问有人能指出我哪里出错了吗?
谢谢!
form_for
字段助手不是那样工作的,他们不会在选项中使用 :value
键。基本上字段的名称 必须 对应于您传递给 form_for
的对象的方法(在您的情况下 @timeline_event
),这就是表单的位置将从中获取值。
如果您想提供自己的字段和值,请使用 _tag
帮手系列,例如:
<%= hidden_field_tag :name_of_field, @sales_opportunity.id %>
或使用f.fields_for
创建子字段(通常结合accepts_nested_attributes_for
)
我不同意@smathy,因为您确实可以像您所做的那样将值显式传递给hidden_field
标记。
但是,这甚至没有必要,因为您正在进行循环分配。我的意思是您在控制器的 edit
操作中声明 @sales_opportunity
并为其分配 @timeline_event.sales_opportunity
的值。
然后您进入视图并尝试将 @timeline_event.sales_opportunity
分配回 @sales_opportunity
。这就是循环逻辑。
如果您正在编辑的 timeline_event
的 sales_opportunity
已经存在,并且您不想让用户对其进行编辑,那么为什么要将其包含在表单中呢?从控制器中的 edit
操作中删除 @sales_opportunity
实例变量,并从视图中完全删除隐藏字段。
看看这样做是否能按预期工作。