【问题标题】:Error after migration from ERB to HAML从 ERB 迁移到 HAML 后出错
【发布时间】:2016-05-31 13:26:25
【问题描述】:

我用http://htmltohaml.com/这个来转换我的ERB,但出现了一些问题。

转换前的工作 ERB

<h3><%= t("admin.labels.employee") %> <%= content_tag(:span, employee_counter) %></h3>
<%
   def create_validation_rules(field_rules)
     Hash[field_rules.map do |rule|
            next ["rule-#{rule[:name]}", rule[:value]] if rule[:value]
            next ["msg-#{rule[:name]}", rule[:msg]] if rule[:msg]
          end] if field_rules
   end
%>
<div class="control-group form-controls">
    <%= f.label :first_name, t("labels.name") %>
    <%= f.text_field :first_name, placeholder: t("labels.first_name"), class: 'js-employeeName', id: "merchant_employees_attributes_#{index}_first_name", name: "merchant[employees_attributes][#{index}][first_name]", autocomplete: "off", maxlength: 50, size: nil, data: create_validation_rules(validations[:first_name]) %>
    <%= f.text_field :middle_name, placeholder: t("labels.middle_name"), id: "merchant_employees_attributes_#{index}_middle_name", name: "merchant[employees_attributes][#{index}][middle_name]", autocomplete: "off", maxlength: 100, size: nil %>
    <%= f.text_field :last_name, placeholder: t("labels.last_name"), class: 'js-employeeName', id: "merchant_employees_attributes_#{index}_last_name", name: "merchant[employees_attributes][#{index}][last_name]", autocomplete: "off", maxlength: 50, size: nil, data: create_validation_rules(validations[:last_name]) %>
</div>
<div class="control-group">
  <%= f.label :email, t("labels.email_address") %>
  <%= f.text_field :email, id: "merchant_employees_attributes_#{index}_email", name: "merchant[employees_attributes][#{index}][email]", autocomplete: "off", maxlength: 250, size: nil, data: create_validation_rules(validations[:email]) %>
</div>
<div class="control-group">
  <% if force_superuser_role %>
      <%= f.hidden_field :superuser, value: "1" %>
  <% else %>
      <%= f.label :superuser, t("admin.labels.superuser") %>
      <%= f.check_box :superuser, class: "superuser_checkbox", id: "merchant_employees_attributes_#{index}_superuser", name: "merchant[employees_attributes][#{index}][superuser]"%>
  <% end %>
</div>

转换后 HAML 不工作:

这是我的错误: 显示第 9 行引发的 /Users/project/app/views/shared/_employee.html.haml:

%h3
  = t("admin.labels.employee")
  = content_tag(:span, employee_counter)
- def create_validation_rules(field_rules)
- Hash[field_rules.map do |rule|
- next ["rule-#{rule[:name]}", rule[:value]] if rule[:value]
- next ["msg-#{rule[:name]}", rule[:msg]] if rule[:msg]
- end] if field_rules
- end
.control-group.form-controls
  = f.label :first_name, t("labels.name")
  = f.text_field :first_name, placeholder: t("labels.first_name"), class: 'js-employeeName', id: "merchant_employees_attributes_#{index}_first_name", name: "merchant[employees_attributes][#{index}][first_name]", autocomplete: "off", maxlength: 50, size: nil, data: create_validation_rules(validations[:first_name])
  = f.text_field :middle_name, placeholder: t("labels.middle_name"), id: "merchant_employees_attributes_#{index}_middle_name", name: "merchant[employees_attributes][#{index}][middle_name]", autocomplete: "off", maxlength: 100, size: nil
  = f.text_field :last_name, placeholder: t("labels.last_name"), class: 'js-employeeName', id: "merchant_employees_attributes_#{index}_last_name", name: "merchant[employees_attributes][#{index}][last_name]", autocomplete: "off", maxlength: 50, size: nil, data: create_validation_rules(validations[:last_name])
.control-group
  = f.label :email, t("labels.email_address")
  = f.text_field :email, id: "merchant_employees_attributes_#{index}_email", name: "merchant[employees_attributes][#{index}][email]", autocomplete: "off", maxlength: 250, size: nil, data: create_validation_rules(validations[:email])
.control-group
  - if force_superuser_role
    = f.hidden_field :superuser, value: "1"
  - else
    = f.label :superuser, t("admin.labels.superuser")
    = f.check_box :superuser, class: "superuser_checkbox", id: "merchant_employees_attributes_#{index}_superuser", name: "merchant[employees_attributes][#{index}][superuser]"

【问题讨论】:

  • 你为什么要在视图中定义一个方法???你在这里自找麻烦。
  • 我可能会建议在别处定义该函数,例如在帮助程序中或在控制器中计算该值。 HAML 和 ERB 不太适合此目的。
  • @ChaseGilliam 实际上,HAML 使得在视图中定义函数变得困难因为函数不应该在视图中定义。

标签: ruby haml erb


【解决方案1】:

处理此问题的正确方法是将方法定义为控制器中的助手:

class MyController
  helper_method :create_validation_rules

private
  def create_validation_rules(field_rules)
    Hash[field_rules.map do |rule|
      next ["rule-#{rule[:name]}", rule[:value]] if rule[:value]
      next ["msg-#{rule[:name]}", rule[:msg]] if rule[:msg]
    end] if field_rules
  end
end

这将允许您从视图中调用create_validation_rules,而不必在那里定义方法。请参阅 In Rails, what exactly do helper and helper_method do? 以准确了解辅助方法是什么以及它是如何工作的。


但是,如果您只是必须在 View 代码中使用嵌入方法,有一个解决方案:您可以简单地消除 inline 函数中的最后一个end,并适当缩进函数和循环。

在这种情况下,错误消息可以解释一切:

您不需要在 Haml 中使用“-end”。取消缩进以关闭一个块

更新您的 HAML 代码,这可行:

%h3
  = t("admin.labels.employee")
  = content_tag(:span, employee_counter)
- def create_validation_rules(field_rules)
  - Hash[field_rules.map do |rule|
    - next ["rule-#{rule[:name]}", rule[:value]] if rule[:value]
    - next ["msg-#{rule[:name]}", rule[:msg]] if rule[:msg]
  - end] if field_rules
.control-group.form-controls
  = f.label :first_name, t("labels.name")
  = f.text_field :first_name, placeholder: t("labels.first_name"), class: 'js-employeeName', id: "merchant_employees_attributes_#{index}_first_name", name: "merchant[employees_attributes][#{index}][first_name]", autocomplete: "off", maxlength: 50, size: nil, data: create_validation_rules(validations[:first_name])
  = f.text_field :middle_name, placeholder: t("labels.middle_name"), id: "merchant_employees_attributes_#{index}_middle_name", name: "merchant[employees_attributes][#{index}][middle_name]", autocomplete: "off", maxlength: 100, size: nil
  = f.text_field :last_name, placeholder: t("labels.last_name"), class: 'js-employeeName', id: "merchant_employees_attributes_#{index}_last_name", name: "merchant[employees_attributes][#{index}][last_name]", autocomplete: "off", maxlength: 50, size: nil, data: create_validation_rules(validations[:last_name])
.control-group
  = f.label :email, t("labels.email_address")
  = f.text_field :email, id: "merchant_employees_attributes_#{index}_email", name: "merchant[employees_attributes][#{index}][email]", autocomplete: "off", maxlength: 250, size: nil, data: create_validation_rules(validations[:email])
.control-group
  - if force_superuser_role
    = f.hidden_field :superuser, value: "1"
  - else
    = f.label :superuser, t("admin.labels.superuser")
    = f.check_box :superuser, class: "superuser_checkbox", id: "merchant_employees_attributes_#{index}_superuser", name: "merchant[employees_attributes][#{index}][superuser]"

由于ERB视图代码中嵌入的函数定义异常,http://htmltohaml.com没有处理好,干脆将整个方法反刍到HAML输出中。虽然这显然是不正确的,但纠正起来很简单。


如果您是一名优秀的网络公民(并且您已经在使用该工具),您将向http://htmltohaml.com 的开发人员报告此问题,以便他可以解决此类 HAML 生成问题。

【讨论】:

  • 今天晚些时候,当我的选票得到补充时,我可以再给你 5 个。 :D
  • 你能帮我做一个类似的问题吗?我将编辑我当前的问题,因为我无法在 2 天内发布新问题
  • @christian 错误是因为content_tag 块不需要end。如果您只是删除第 13、17、21 行等处的 end 行,这应该可以工作。当您可以发布新问题时,然后发布此问题,并将此答案回滚到原始答案,以便此问题和答案不会冲突。
【解决方案2】:

最好的选择是将create_validation_rules 移动到帮助器中,或者至少将其设置为控制器中的helper_method

要将其保存在 haml - 您必须对块使用 haml 语法:

- def create_validation_rules(field_rules)
  - if field_rules
    - Hash.[] field_rules.map do |rule|
      - if rule[:value]
        - next ["rule-#{rule[:name]}", rule[:value]]
      - if rule[:msg]
        - next ["msg-#{rule[:name]}", rule[:msg]]

【讨论】:

    猜你喜欢
    • 2020-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-16
    • 1970-01-01
    • 1970-01-01
    • 2020-10-17
    相关资源
    最近更新 更多