【问题标题】:Rails render_to_string with partial that requires a form builder object?Rails render_to_string with partial 需要表单构建器对象?
【发布时间】:2021-07-29 04:43:51
【问题描述】:

我觉得这很简单,我完全想念它..

我有一个 edit.html.erb 文件,里面有类似的东西;

<%= form_for @some_object, html: { autocomplete: "off" } do |f| %>
  <%= render 'form', f: f %>
<% end %>

它所引用的_form.html.erb 文件中包含与此类似的内容;

<%= f.fields_for :some_nested_object, @some_object.some_nested_object.order(:sort_order) do |obj| %>
    foobarbaz form stuff..
<% end %>

我无法更改编辑或部分表单。网站的很大一部分都需要它们。它就是这样,我坚持这一点。

我希望能够将带有 f.fields_for 的表单部分呈现为 json 结果中的字符串。

def index
  respond_to do |format|
    format.json { render json: { html: render_to_string('/path/to/_form.html.erb',
                                                        layout: false,
                                                        locals: { f: ????????? }
  end
end

但是,我不确定在这种情况下如何分配f

我觉得它应该类似于

locals: { f: ActionView::Helpers::FormHelper::form_for(@some_object) }

或类似的东西,但这显然不起作用。

感觉这应该很简单,我只是个白痴..

想法? (关于这个问题,不是我是白痴=)

【问题讨论】:

    标签: ruby-on-rails ruby render-to-string


    【解决方案1】:

    你可以创建ActionView::Helpers::FormBuilder的实例:

    def index
      f = ActionView::Helpers::FormBuilder.new(
         'object_name', # the scope for the inputs
         object,        # object wrapped by the form builder
         view_context,  # the template where the form builder can call the tag helpers on 
         {}             # options
      )
      respond_to do |format|
        format.json do
          html = render_to_string(
                   '/path/to/_form.html.erb',
                   layout: false,
                   locals: { f: f }
                 )
          render json: { html: html } 
        end
      end
    end
    

    【讨论】:

    • 我试过了.. 它抱怨它缺少块.. ``` Missing block Extracted source (about line #431): #429 # #430 def form_for(record, options = {}, &block) *431 raise ArgumentError, "Missing block" 除非 block_given? ```在这种情况下我如何通过黑色?
    • 我猜想就像使用任何其他 Ruby 方法一样 - view_context.form_for(@some_object) {}view_context.form_for(@some_object) do; end
    • 所以我尝试了{}do;end,它们都在第一个f.fields_for 出现错误,此错误ActionView::Template::Error (undefined method fields_for' for #<:safebuffer:0x0000000116b1d598>):` .我什至不知道安全缓冲区是什么哈哈
    • 我删除了我的答案,因为我跳过了枪并且没有考虑form_for - form_with 当然返回字符串的事实。通过编辑挽救。
    • 嗯,谢谢你,你用 view_context 方法给了我答案,我根本没想过..谢谢。
    【解决方案2】:

    好的,看看这个 hacky hack:

    def index
      respond_to do |format|
    
        format.json do
          form_builder = view_context.form_for(@some_object) { |builder| break builder }
    
          html = render_to_string(
            '/path/to/_form.html.erb',
            layout: false,
            locals: { f: form_builder }
          )
          render json: { html: html } 
        end
      end
    end
    

    正在回答(假设它确实有效)请注意这是一个 hack。这不是我们应该编写代码的方式(尽管有时我们必须这样做),下一步是弄清楚为什么我们必须做这样的黑客行为。

    例如,您是否有机会重新发明cocoon gem?

    【讨论】:

    • 所以 Max 给了我这个想法,你也说了同样的话.. 我希望他没有删除他的评论我会给他 +1.. 我没想过使用 vew_context 并且有效正如你所展示的那样完美......谢谢
    • 也只是一般性评论,有时我们会陷入遗留代码,我们必须为其编写东西并且无法控制......这是其中一种情况......使用view_context.form_for(@some_object) { |f| @formBuilder = f }然后@ 987654324@ 工作并解决了这个问题。肯定不是一个干净的解决方案.. 但此时整个代码库重构超出了项目的范围(认为它真的需要它)
    • 我挽救了我的答案,但不确定f = ActionView::Helpers::FormBuilder.new('object_name', object, view_context, {}) 是否不那么老套。
    • 更新:这实际上是行不通的。有一些奇怪的错误,其中部分正常完美呈现,但是当你使用上面的这个方法(所有这些)时,任何时候你在代码中执行&lt;%= whatever %&gt; 它会导致在输出中挂起&amp;lt;/div&amp;gt;,即使有没有打开的 div 或类似的东西。这几乎感觉像是表单构建器助手中的一个错误..
    • @JasonEllis 是wahteverhtml_safe 的输出吗?
    猜你喜欢
    • 1970-01-01
    • 2017-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-27
    • 2022-06-16
    • 1970-01-01
    相关资源
    最近更新 更多