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

时间:2016-02-07 12:27:16

标签: ruby-on-rails ruby metaprogramming

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

我已经实现的解决方案有效,但是不灵活并且有很多开销。我想知道是否有更好的方法。

在我看来:

<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中的视图字段,并且还以干净的方式将它们与实际字段完全分开。

有什么建议吗?

1 个答案:

答案 0 :(得分:2)

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

@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%>

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