半全局Rails部分

时间:2017-10-26 20:38:15

标签: ruby-on-rails ruby ruby-on-rails-4 partials

有没有更好的方法来实现我想要的目标?

  • 我在Runnable文件夹中有一部分,其中包含用于发送电子邮件的表单中的所有字段。
  • 一个帮助器方法,使用默认选项呈现所述部分(executor.submit(downloadTask); resultList.add(downloadTask); ,其中/views/shared/是默认变量的哈希值。)
  • 每个表单的辅助方法,用于发送调用上述帮助方法的电子邮件,并传入render partial: 'shared/email_fields' locals: locals对象或包含locals html属性开头的字符串。

我遇到的问题:大多数电子邮件表单略有不同,这导致我必须在FormBuilder哈希中添加其他选项,我觉得全局部分变得臃肿。是否有某种方式以这种方式使用全局部分,使得部分不会变得超级膨胀?

我想过让每个表单完全分开,但对于保养和干燥都不好。我想过传递一个局部的名称要在全局局部内部渲染,但是这些形式中的一些需要相同的选项,并且是从不同的控制器渲染的,我不想放一些局部的在name文件夹中不是全局的。现在,我只是坚持臃肿的全球部分。

任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:1)

以下是我的表现方式。这听起来很奇怪,但请耐心等待。

所以,我的应用程序基本上有两种形式。对于通过javascript提交的表单,它看起来像这样:

#views/shared/_remote_form.html.haml

= form_tag @presenter.form_path, 
    remote: true, 
    id: @presenter.form_id, 
    class: @presenter.form_classes, 
    data: @presenter.form_data, 
    method: @presenter.form_method do 
    .well
      = @presenter.form_inner
      .form-controls-container
        .form-controls-wrapper
          = @presenter.form_controls

如您所见,我使用演示者。演示者在相关控制器中实例化为控制器变量,以便演示者可用于部分。类似的东西:

class FooController < ApplicationController

  def new
    @presenter = NewFooFormPresenter.new(self)
    render partial: 'shared/remote_form'
  end

  ...

end

您可以看到我在控制器中传递,以便演示者能够呈现表单的各个部分。

所有FormPresenters都继承自FormPresenterBase,其中包含表单中调用的每个方法的存根方法。像这样:

class FormPresenterBase

  def initialize(controller)
    @controller = controller
  end

  def form_path
    root_path
  end

  def form_id
    'bogus-form-id'
  end

  def form_classes
    'something-bogus'
  end

  def form_inner; end

  def form_controls; end

  ...

end

让我自己引导表单而不会一直抛出一堆错误。当然,这种存根形式确实无法正常工作,但这是可以的,因为每个FormPresenter都会用实际值覆盖存根方法。所以,像:

class NewFooFormPresenter < FormPresenterBase

  def form_path
    new_for_form_path
  end

  def form_id
   'new-foo-form'
  end 

  def form_classes
    'something-not-bogus'
  end

  # The form fields could be unique to this form. Or, I might have a set of common 
  # fields that I use across multiple forms. I just decide which partial has the 
  # correct set of fields and render it here.
  def form_inner
    render partial: 'new_inner_fields'
  end

  # The controls are also rendered from partials. Here, I want to have an okay 
  # button and a cancel button. So, I just call the correct partial that 
  # renders those. I call html_safe on the resultant string so that it renders 
  # correctly.
  def form_controls
    [:okay, :cancel].each_with_object("") do |control_sym, to_return|
      render partial: "shared/form_widgets/#{control_sym.to_s}_button"
    end.html_safe

  end

  ...

end

当然,我的FormPresenters可能会变得棘手。如果有共享公共方法的系列,我可以使用进一步的继承或模块包含来保持所有DRY。

因此,一旦我将所有基本的窗体小部件(字段组合,控件等)配置为局部窗口,我就可以在我的演示者中混合搭配,让我感到非常高兴。而且(至少对形式而言),我基本上不必再为我的余生写下另一部分内容了。每当我需要一个新变种时,我只需启动一个新的FormPresenter并自定义它以给我我想要的形式。

实际上,它比所有这些都要多一点,但希望这能让你感觉到另一种方法可以给猫皮肤涂抹。

答案 1 :(得分:0)

一种方法是为每个表单分别设置一个部分。获取表单共有的所有项目并将它们放在一起。然后,您可以参考&#34;常用项目&#34;部分在你的个人形式部分。根据表单的结构,您可能会有几个常见的项目和#34;偏,但没关系。目标是保持代码组织和干燥。