元编程或其他更好的方法来处理 Rails 中的虚拟视图字段 4

Metaprogramming or other better way to handle virtual view fields in Rails 4

在我的应用程序中,我有大量的虚拟字段。虚拟字段是我在视图上调用的输入字段,它驱动控制器中的某些行为,但不存储在数据库中。

我实施的解决方案有效,但不灵活且开销很大。请问有没有更好的办法

在我看来:

<div class="row">
  <div class="col-md-3">
    <%= f.input :present_indicatif, :as => :boolean, label: "Présent de l'indicatif", :input_html => { checked: false } %>
  </div>
  <div class="col-md-3">
    <%= f.input :imparfait_indicatif, :as => :boolean, label: "Imparfait de l'indicatif", :input_html => { checked: false } %>
  </div>
  <div class="col-md-3">
    <%= f.input :passe_simple_indicatif, :as => :boolean, label: "Passé simple", :input_html => { checked: false } %>
  </div>
  <div class="col-md-3">
    <%= f.input :futur_anterieur_indicatif, :as => :boolean, label: "Futur", :input_html => { checked: false } %>
  </div>
</div>

以及更多字段。

然后我在控制器中将虚拟字段与实际数据库字段分开

    def deck_params
      params.require(:deck).permit(:deck, :fluent_language,  :target_language, :status, :user_id, :deck_type, :all_verbs,
                              :present_indicatif, :imparfait_indicatif, :passe_simple_indicatif ... etc ...]
                              )
    end

    def deck_only_params
      deck_params.select { |k,v| [:deck, :fluent_language, :target_language, :status, :user_id, :deck_type].include?(k.to_sym) }
    end

    def virtual_params
      vp = params.require(:deck).select { |k,v| [
    :present_indicatif, :imparfait_indicatif, :passe_simple_indicatif, :futur_anterieur_indicatif,
    :passe_anterieur, ... etc ...
      ].include?(k.to_sym) }
      res = vp.reject { |k,v| v == "0" }
      res
    end

理想情况下,我想将虚拟字段列表存储在数组或散列中,并遍历它们以在 erb 中生成视图字段,并以干净的方式使它们与实际字段完全分开。

有什么建议吗?

在我看来,每个虚拟字段都会有一个自定义标签。为什么不创建一个名称和标签数组:

@virtual_fields = [{field:'field_1',label:'Field Number One'},{field:'field_2',label:'Field Number Two'},{field:'field_3',label:'Field Number Three'}]

在您看来

<%virtual_fields.each do |vf|%>
  <div class="col-md-3">
    <%= f.input @model_with_vf.send(vf[:field]), :as => :boolean, label: vf[:label], :input_html => { checked: false } %>
  </div>
<%end%>

这当然可以进一步抽象,以将字段的实际标签移动到模型中,并具有一个函数,可以接收字段名称并检索标签。