Ruby on rails Rails服务器提升";回收物品“;按对象\u id创建实例时有时会出错
我的问题是,当使用Ruby on rails Rails服务器提升";回收物品“;按对象\u id创建实例时有时会出错,ruby-on-rails,ruby,ajax,nested-forms,Ruby On Rails,Ruby,Ajax,Nested Forms,我的问题是,当使用ajax以Rails的方式动态地添加表单的一部分时,就会出现这种情况。异步请求是在节点对象的事件输入发生时发出的,并且它正在工作。她将dataaction属性中定义的stock\u component\u f.object\u id发送给控制器,并且定义了一个助手方法form\u parent,以便根据部分stock\u component\u字段访问。haml 这是我的表格 = form_for @stock_ingredient, remote: true do |stoc
ajax
以Rails
的方式动态地添加表单的一部分时,就会出现这种情况。异步请求是在节点
对象的事件输入
发生时发出的,并且它正在工作。她将dataaction
属性中定义的stock\u component\u f.object\u id
发送给控制器,并且定义了一个助手方法form\u parent
,以便根据部分stock\u component\u字段访问。haml
这是我的表格
= form_for @stock_ingredient, remote: true do |stock_ingredient_f|
.field
= stock_ingredient_f.label "Enable/disable keyboard"
= check_box :keyboard, :handler
.field
= stock_ingredient_f.label "Barcode"
= text_field :ingredient, :barcode, value: stock_ingredient_f.object.ingredient.try(:barcode), class: "barcode", :'data-action' => ingredient_async_path(form_parent_object_id: stock_ingredient_f.object_id)
- if @stock_ingredient.stock.present?
.field
= stock_ingredient_f.label "Stock"
= stock_ingredient_f.number_field :stock
%span.brown-color
= "(#{@stock_ingredient.ingredient.net_weight_unit})"
这是一个应该动态加载的部分
.ingredient-data
.field
%dl
.line
%dt
Ingredient:
%dd
= "#{@ingredient.name}"
.line
%dt
Stock:
%dd.stock
= "#{MeasurementUnits.humanize_for @ingredient.stock_ingredient.stock, resolve_unit_type(@ingredient.net_weight_unit)}"
.field
/ the problem is raised here
= form_parent.label "Stock"
= form_parent.number_field :stock
%span.brown-color
= "(#{@ingredient.net_weight_unit})"
.field
= form_parent.submit "Save"
= form_parent.button "Cancel", type: :reset
这是我的应用程序\u controller.rb
,其中定义了方法表单\u parent
class ApplicationController < ActionController::Base
respond_to :html, :js
# Prevent CSRF attacks by raising an exception.
# protect_from_forgery with: :exception
# when will has it login, change this line
protect_from_forgery with: :exception, if: Proc.new { |c| c.request.format != 'application/json' }
protect_from_forgery with: :null_session, if: Proc.new { |c| c.request.format == 'application/json' }
def form_parent
ObjectSpace._id2ref(params[:form_parent_object_id].to_i) if params[:form_parent_object_id]
end
helper_method :form_parent
def root
render "layouts/application", layout: false
end
protected
def id
params[:id]
end
def redirect_for_async_request location
render js: "window.location='#{location}'"
end
def alert message
render js: "window.alert('#{message}')"
end
# def no_cache
# if Rails.env.development?
# response.headers["Cache-Control"] = "no-cache, must-revalidate, max-age=0"
# end
# end
end
表格
= form_for @stock_ingredient, remote: true do |stock_ingredient_f|
- store_form stock_ingredient_f
.field
= stock_ingredient_f.label "Enable/disable keyboard"
= check_box :keyboard, :handler
.field
= stock_ingredient_f.label "Barcode"
= text_field :ingredient, :barcode, value: stock_ingredient_f.object.ingredient.try(:barcode), class: "barcode", :'data-action' => ingredient_async_path
- if @stock_ingredient.stock.present?
.field
= stock_ingredient_f.label "Stock"
= stock_ingredient_f.number_field :stock
%span.brown-color
= "(#{@stock_ingredient.ingredient.net_weight_unit})"
您猜对了-具有该对象\u id的对象已被垃圾收集。我不知道你为什么要这样做,但这听起来是个非常糟糕的主意。我不完全清楚什么是
form\u parent
(FormBuilder实例?),但我猜您应该在数据库中传递对象的id,从数据库中获取对象,并使用该id从form\u中为或字段为获取新的FormBuilder
实例
即使您可以使用当前的方法,它也会将您限制为单个rails实例,而任何应用程序的严肃部署都会使用分布在2台或更多服务器上的多个实例 此错误表示您正试图访问已被垃圾收集的对象,这可能是您所怀疑的。发生这种情况是因为对象id来自上一次,并且一旦id发送到浏览器,就不再存在对该对象的引用,因此ruby清理了该对象
尽管这可能并不总是正确的,但最好将每个请求都视为在一个新的、独立的ruby进程中运行。如果希望在请求之间“传递”数据,则必须将其发送到客户端(如果不介意更改数据),或者将其存储在会话中,或者将其存储在数据库中。您不能像这里那样传递对象。是的,form\u parent
返回一个FormBuilder
实例。谢谢。我将它存储在一个类变量中,因为它不是在会话中创建的。
= form_for @stock_ingredient, remote: true do |stock_ingredient_f|
- store_form stock_ingredient_f
.field
= stock_ingredient_f.label "Enable/disable keyboard"
= check_box :keyboard, :handler
.field
= stock_ingredient_f.label "Barcode"
= text_field :ingredient, :barcode, value: stock_ingredient_f.object.ingredient.try(:barcode), class: "barcode", :'data-action' => ingredient_async_path
- if @stock_ingredient.stock.present?
.field
= stock_ingredient_f.label "Stock"
= stock_ingredient_f.number_field :stock
%span.brown-color
= "(#{@stock_ingredient.ingredient.net_weight_unit})"